From 90cc2d1282b8e532bfff08872f4dd742aeff5582 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sat, 25 Apr 2020 21:28:43 +0300 Subject: [PATCH 01/76] #ZEXSM#add secure travis#fix travis release --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 28e51516..c5b97e82 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,9 @@ dist: trusty os: linux mono: none dotnet: 2.1.502 +env: + global: + - secure: SuKoVIfbXNAQQAQ8FhoK/USbDAJld63DKsBkmqONvUyOm8rBzFPkAfIl0qACKMMVJec7aJ9PhfxBA8nJdh7zCuaw0xcGxnVfQaxtegKo8+yz18LtUDnwv7h2aDDpsL5IdtgNZabusoz0CG0RB2vZEUQCbx80oH41L0Ijcya93ngnVeD4u0PdoFXbqxoBTiadI6qh/Od+jD+6+B04fz2XSa16WSjobSwsYNr5M+CIpa9OmLdZAJkvgHFlshmrAD2oE8iddImB9YIjDqCvnH/jqAP3/Eqci/N5sW5qpgRAyhvRxcI3Gev0wFexN8qMBUB3Iim92hf18s30R9K0Bvbb/Q+HX/VgnIBY8Yy3F68YNQvmga5AoODyuLaqPBe6ptckFp6yPkPBqeQgp1Pu2mySL0tFkjvg6/WWsxLVpco7zCjymF1IDhjVgbeO+rAQ5vEs1Fp89o4mpIAOcP10uM2b3W71fFSWTbKvIyp8ozL8PaTkRq5NiS7NvQ85hE/lVJyCL62vZ1YYOeQb0ArdoCZVdHbZp9L3UAIPYGUW6mJ9PlQtm9RC3hsnBJEvpoBnQl1wx25hhnTt16oif6L8h5XAbgVpW0Bd46LXMQbMXHKFyeMTuH4l94N9HD+qiDh82L95EQk+yHeCmfZqoKE+pf7HuscvHiFLkOxNbtJdPXqF99k= branches: only: - master @@ -31,7 +34,7 @@ before_deploy: - dotnet pack -c $CONFIGURATION -p:PackageVersion=$PACKAGE_VERSION deploy: provider: releases - name: v$CURRENT_TAG + name: v$PACKAGE_VERSION token: $GITHUB_OAUTH_TOKEN cleanup: true repo: ZEXSM/OData.QueryBuilder From bb5ea0d5b73d27cfb355969e9ed389412e91c4da Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Mon, 4 May 2020 23:44:15 +0300 Subject: [PATCH 02/76] #ZEXSM#go to expression visitor --- .../Nested/ODataQueryNestedBuilder.cs | 2 +- .../Builders/ODataQueryBuilder.cs | 8 +- .../ODataQueryExpressionVisitor.cs | 193 ++++++++++++++++++ .../Extensions/ExpressionExtension.cs | 77 +++---- .../Extensions/ReflectionExtension.cs | 8 +- src/OData.QueryBuilder/Parameters/Contants.cs | 25 +++ .../Nested/ODataQueryNestedParameter.cs | 55 +++-- .../Nested/ODataQueryNestedParameterBase.cs | 2 +- .../Parameters/ODataQueryParameterKey.cs | 30 ++- .../Parameters/ODataQueryParameterList.cs | 60 ++++-- 10 files changed, 365 insertions(+), 95 deletions(-) create mode 100644 src/OData.QueryBuilder/Expressions/ODataQueryExpressionVisitor.cs create mode 100644 src/OData.QueryBuilder/Parameters/Contants.cs diff --git a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs index 5903f7e4..f308db4e 100644 --- a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs @@ -14,7 +14,7 @@ public class ODataQueryNestedBuilder : IODataQueryNestedBuilder _queryBuilder = new StringBuilder(); - public string Query => $"{_queryBuilder.ToString()}({_odataQueryNestedParameter.Query})"; + public string Query => $"{_queryBuilder}({_odataQueryNestedParameter.Query})"; public IODataQueryNestedParameter For(Expression> nestedEntityExpand) { diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index 4e6a0aed..025478f1 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.Extensions; +using OData.QueryBuilder.Expressions; using OData.QueryBuilder.Resourses; using System; using System.Linq.Expressions; @@ -17,9 +17,11 @@ public ODataQueryBuilder(string baseUrl) => public IODataQueryResource For(Expression> entityResource) { - var entityResourceQuery = entityResource.Body.ToODataQuery(string.Empty); + var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); + odataQueryExpressionVisitor.Visit(entityResource.Body); + var odataResourceQuery = odataQueryExpressionVisitor.GetODataQuery(); - return new ODataQueryResource($"{_baseUrl}{entityResourceQuery}"); + return new ODataQueryResource($"{_baseUrl}{odataResourceQuery}"); } } } \ No newline at end of file diff --git a/src/OData.QueryBuilder/Expressions/ODataQueryExpressionVisitor.cs b/src/OData.QueryBuilder/Expressions/ODataQueryExpressionVisitor.cs new file mode 100644 index 00000000..ab4bb1f6 --- /dev/null +++ b/src/OData.QueryBuilder/Expressions/ODataQueryExpressionVisitor.cs @@ -0,0 +1,193 @@ +using OData.QueryBuilder.Extensions; +using System.Linq.Expressions; +using System.Text; + +namespace OData.QueryBuilder.Expressions +{ + internal class ODataQueryExpressionVisitor : ExpressionVisitor + { + private readonly StringBuilder _queryBuilder; + + public ODataQueryExpressionVisitor() + : base() => + _queryBuilder = new StringBuilder(); + + public string GetODataQuery() => _queryBuilder.ToString(); + + public override Expression Visit(Expression node) + { + return base.Visit(node); + } + + protected override Expression VisitBinary(BinaryExpression node) + { + return base.VisitBinary(node); + } + + protected override Expression VisitBlock(BlockExpression node) + { + return base.VisitBlock(node); + } + + protected override CatchBlock VisitCatchBlock(CatchBlock node) + { + return base.VisitCatchBlock(node); + } + + protected override Expression VisitConditional(ConditionalExpression node) + { + return base.VisitConditional(node); + } + + protected override Expression VisitConstant(ConstantExpression node) + { + return base.VisitConstant(node); + } + + protected override Expression VisitDefault(DefaultExpression node) + { + return base.VisitDefault(node); + } + + protected override ElementInit VisitElementInit(ElementInit node) + { + return base.VisitElementInit(node); + } + + protected override Expression VisitExtension(Expression node) + { + return base.VisitExtension(node); + } + + protected override Expression VisitGoto(GotoExpression node) + { + return base.VisitGoto(node); + } + + protected override Expression VisitIndex(IndexExpression node) + { + return base.VisitIndex(node); + } + + protected override Expression VisitInvocation(InvocationExpression node) + { + return base.VisitInvocation(node); + } + + protected override Expression VisitLabel(LabelExpression node) + { + return base.VisitLabel(node); + } + + protected override LabelTarget VisitLabelTarget(LabelTarget node) + { + return base.VisitLabelTarget(node); + } + + protected override Expression VisitLambda(Expression node) + { + return base.VisitLambda(node); + } + + protected override Expression VisitListInit(ListInitExpression node) + { + return base.VisitListInit(node); + } + + protected override Expression VisitLoop(LoopExpression node) + { + return base.VisitLoop(node); + } + + protected override Expression VisitMember(MemberExpression node) + { + _queryBuilder.Append(node.Member.Name); + + return base.VisitMember(node); + } + + protected override MemberAssignment VisitMemberAssignment(MemberAssignment node) + { + return base.VisitMemberAssignment(node); + } + + protected override MemberBinding VisitMemberBinding(MemberBinding node) + { + return base.VisitMemberBinding(node); + } + + protected override Expression VisitMemberInit(MemberInitExpression node) + { + return base.VisitMemberInit(node); + } + + protected override MemberListBinding VisitMemberListBinding(MemberListBinding node) + { + return base.VisitMemberListBinding(node); + } + + protected override MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding node) + { + return base.VisitMemberMemberBinding(node); + } + + protected override Expression VisitMethodCall(MethodCallExpression node) + { + return base.VisitMethodCall(node); + } + + protected override Expression VisitNew(NewExpression node) + { + for (var i = 0; i < node.Arguments.Count; i++) + { + Visit(node.Arguments[i]); + + if (i != node.Arguments.Count - 1) + { + _queryBuilder.Append(","); + } + } + + return default; + } + + protected override Expression VisitNewArray(NewArrayExpression node) + { + return base.VisitNewArray(node); + } + + protected override Expression VisitParameter(ParameterExpression node) + { + return base.VisitParameter(node); + } + + protected override Expression VisitSwitch(SwitchExpression node) + { + return base.VisitSwitch(node); + } + + protected override SwitchCase VisitSwitchCase(SwitchCase node) + { + return base.VisitSwitchCase(node); + } + + protected override Expression VisitTry(TryExpression node) + { + return base.VisitTry(node); + } + + protected override Expression VisitTypeBinary(TypeBinaryExpression node) + { + return base.VisitTypeBinary(node); + } + + protected override Expression VisitUnary(UnaryExpression node) + { + var odataLogicalOperator = node.GetODataLogicalOperator(); + + _queryBuilder.Append(odataLogicalOperator); + + return base.VisitUnary(node); + } + } +} diff --git a/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs b/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs index fc836349..34da53d4 100644 --- a/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs +++ b/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs @@ -7,6 +7,37 @@ namespace OData.QueryBuilder.Extensions { internal static class ExpressionExtension { + public static string GetODataLogicalOperator(this Expression expression, bool isSpaceToEnd = true) + { + var spaceEnd = isSpaceToEnd ? " " : string.Empty; + + switch (expression.NodeType) + { + case ExpressionType.And: + case ExpressionType.AndAlso: + return $"and{spaceEnd}"; + case ExpressionType.Or: + case ExpressionType.OrElse: + return $"or{spaceEnd}"; + case ExpressionType.Equal: + return $"eq{spaceEnd}"; + case ExpressionType.Not: + return $"not{spaceEnd}"; + case ExpressionType.NotEqual: + return $"ne{spaceEnd}"; + case ExpressionType.LessThan: + return $"lt{spaceEnd}"; + case ExpressionType.LessThanOrEqual: + return $"le{spaceEnd}"; + case ExpressionType.GreaterThan: + return $"gt{spaceEnd}"; + case ExpressionType.GreaterThanOrEqual: + return $"ge{spaceEnd}"; + default: + return string.Empty; + } + } + public static object GetMemberExpressionValue(this MemberExpression memberExpression) { if (memberExpression.Expression is ConstantExpression) @@ -59,35 +90,6 @@ public static string GetInSequence(this object arrayObj) return string.Empty; } - public static string ToODataOperator(this ExpressionType expressionType) - { - switch (expressionType) - { - case ExpressionType.And: - case ExpressionType.AndAlso: - return "and"; - case ExpressionType.Or: - case ExpressionType.OrElse: - return "or"; - case ExpressionType.Equal: - return "eq"; - case ExpressionType.Not: - return "not"; - case ExpressionType.NotEqual: - return "ne"; - case ExpressionType.LessThan: - return "lt"; - case ExpressionType.LessThanOrEqual: - return "le"; - case ExpressionType.GreaterThan: - return "gt"; - case ExpressionType.GreaterThanOrEqual: - return "ge"; - default: - return string.Empty; - } - } - public static string ToODataQuery(this ConstantExpression constantExpression) { switch (constantExpression.Value) @@ -150,16 +152,16 @@ public static string ToODataQueryFunctionDate(this BinaryExpression binaryExpres .Invoke(rightNewExpression.Arguments.Select(s => ((ConstantExpression)s).Value).ToArray())) .ToString("yyyy-MM-dd"); - return $"date({leftQuery}) {binaryExpression.NodeType.ToODataOperator()} {rightQueryNew}"; + return $"date({leftQuery}) {binaryExpression.GetODataLogicalOperator()} {rightQueryNew}"; case MemberExpression rightMemberExpression: var rightQueryMember = ((DateTime)rightMemberExpression.GetMemberExpressionValue()) .ToString("yyyy-MM-dd"); - return $"date({leftQuery}) {binaryExpression.NodeType.ToODataOperator()} {rightQueryMember}"; + return $"date({leftQuery}) {binaryExpression.GetODataLogicalOperator()} {rightQueryMember}"; case ConstantExpression rightConstantExpression: var rightQueryConstant = rightConstantExpression.ToODataQuery(); - return $"date({leftQuery}) {binaryExpression.NodeType.ToODataOperator()} {rightQueryConstant}"; + return $"date({leftQuery}) {binaryExpression.GetODataLogicalOperator()} {rightQueryConstant}"; } } else @@ -175,16 +177,16 @@ public static string ToODataQueryFunctionDate(this BinaryExpression binaryExpres var rightQueryUnary = ((DateTime)memberExpression.GetMemberExpressionValue()) .ToString("O"); - return $"{leftQuery} {binaryExpression.NodeType.ToODataOperator()} {rightQueryUnary}"; + return $"{leftQuery} {binaryExpression.GetODataLogicalOperator()} {rightQueryUnary}"; case MemberExpression rightMemberExpression: var rightQueryMember = ((DateTime)rightMemberExpression.GetMemberExpressionValue()) .ToString("O"); - return $"{leftQuery} {binaryExpression.NodeType.ToODataOperator()} {rightQueryMember}"; + return $"{leftQuery} {binaryExpression.GetODataLogicalOperator()} {rightQueryMember}"; case ConstantExpression rightConstantExpression: var rightQueryConstant = rightConstantExpression.ToODataQuery(); - return $"{leftQuery} {binaryExpression.NodeType.ToODataOperator()} {rightQueryConstant}"; + return $"{leftQuery} {binaryExpression.GetODataLogicalOperator()} {rightQueryConstant}"; } } } @@ -217,7 +219,7 @@ public static string ToODataQuery(this Expression expression, string queryString return leftQueryString; } - return $"{leftQueryString} {binaryExpression.NodeType.ToODataOperator()} {rightQueryString}"; + return $"{leftQueryString} {binaryExpression.GetODataLogicalOperator()} {rightQueryString}"; case MemberExpression memberExpression: var memberExpressionValue = memberExpression.GetMemberExpressionValue(); @@ -314,8 +316,7 @@ public static string ToODataQuery(this Expression expression, string queryString return newExpression.ToODataQuery(); case UnaryExpression unaryExpression: - var odataOperator = unaryExpression.NodeType.ToODataOperator(); - odataOperator = !string.IsNullOrEmpty(odataOperator) ? $"{odataOperator} " : string.Empty; + var odataOperator = unaryExpression.GetODataLogicalOperator(); return $"{odataOperator}{unaryExpression.Operand.ToODataQuery(queryString)}"; diff --git a/src/OData.QueryBuilder/Extensions/ReflectionExtension.cs b/src/OData.QueryBuilder/Extensions/ReflectionExtension.cs index 6efa56f8..232b65a1 100644 --- a/src/OData.QueryBuilder/Extensions/ReflectionExtension.cs +++ b/src/OData.QueryBuilder/Extensions/ReflectionExtension.cs @@ -5,7 +5,7 @@ namespace OData.QueryBuilder.Extensions { internal static class ReflectionExtension { - public static object GetValue(this MemberInfo memberInfo, object obj = default(object)) + public static object GetValue(this MemberInfo memberInfo, object obj = default) { try { @@ -14,14 +14,14 @@ internal static class ReflectionExtension case FieldInfo fieldInfo: return fieldInfo.GetValue(obj); case PropertyInfo propertyInfo: - return propertyInfo.GetValue(obj, default(object[])); + return propertyInfo.GetValue(obj, default); default: - return default(object); + return default; } } catch (Exception) { - return default(object); + return default; } } } diff --git a/src/OData.QueryBuilder/Parameters/Contants.cs b/src/OData.QueryBuilder/Parameters/Contants.cs new file mode 100644 index 00000000..766eebe8 --- /dev/null +++ b/src/OData.QueryBuilder/Parameters/Contants.cs @@ -0,0 +1,25 @@ +namespace OData.QueryBuilder.Parameters +{ + internal struct Contants + { + public const string QueryStringSeparator = "&"; + public const char QueryCharSeparator = '&'; + public const string QueryStringNestedSeparator = ";"; + public const char QueryCharNestedSeparator = ';'; + public const string QueryStringBegin = "?"; + public const char QueryCharBegin = '?'; + public const string QueryStringEqualSign = "="; + public const char QueryCharEqualSign = '='; + + public const string QueryParameterSelect = "$select"; + public const string QueryParameterExpand = "$expand"; + public const string QueryParameterFilter = "$filter"; + public const string QueryParameterOrderBy = "$orderby"; + public const string QueryParameterTop = "$top"; + public const string QueryParameterSkip = "$skip"; + public const string QueryParameterCount = "$count"; + + public const string QuerySortAsc = "asc"; + public const string QuerySortDesc = "desc"; + } +} diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs index f951d2ca..52c5556a 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs @@ -1,4 +1,5 @@ using OData.QueryBuilder.Builders.Nested; +using OData.QueryBuilder.Expressions; using OData.QueryBuilder.Extensions; using System; using System.Linq.Expressions; @@ -12,65 +13,85 @@ public ODataQueryNestedParameter() { } - public IODataQueryNestedParameter Expand(Expression> entityExpandNested) + public IODataQueryNestedParameter Expand(Expression> entityNestedExpand) { - var entityExpandNestedQuery = entityExpandNested.Body.ToODataQuery(string.Empty); + var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); - _queryBuilder.Append($"$expand={entityExpandNestedQuery};"); + odataQueryExpressionVisitor.Visit(entityNestedExpand.Body); + + var odataNestedExpandQuery = odataQueryExpressionVisitor.GetODataQuery(); + + _queryBuilder.Append($"{Contants.QueryParameterExpand}{Contants.QueryStringEqualSign}{odataNestedExpandQuery}{Contants.QueryStringNestedSeparator}"); return this; } - public IODataQueryNestedParameter Expand(Action> entityExpandNested) + public IODataQueryNestedParameter Expand(Action> actionEntityExpandNested) { var odataQueryNestedBuilder = new ODataQueryNestedBuilder(); - entityExpandNested(odataQueryNestedBuilder); + actionEntityExpandNested(odataQueryNestedBuilder); - _queryBuilder.Append($"$expand={odataQueryNestedBuilder.Query};"); + _queryBuilder.Append($"{Contants.QueryParameterExpand}{Contants.QueryStringEqualSign}{odataQueryNestedBuilder.Query}{Contants.QueryStringNestedSeparator}"); return this; } public IODataQueryNestedParameter Filter(Expression> entityNestedFilter) { - var entityNestedFilterQuery = entityNestedFilter.Body.ToODataQuery(string.Empty); + var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); + + odataQueryExpressionVisitor.Visit(entityNestedFilter.Body); - _queryBuilder.Append($"$filter={entityNestedFilterQuery};"); + var odataNestedFilterQuery = odataQueryExpressionVisitor.GetODataQuery(); + + _queryBuilder.Append($"{Contants.QueryParameterFilter}{Contants.QueryStringEqualSign}{odataNestedFilterQuery}{Contants.QueryStringNestedSeparator}"); return this; } public IODataQueryNestedParameter OrderBy(Expression> entityNestedOrderBy) { - var entityNestedOrderByQuery = entityNestedOrderBy.Body.ToODataQuery(string.Empty); + var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); + + odataQueryExpressionVisitor.Visit(entityNestedOrderBy.Body); - _queryBuilder.Append($"$orderby={entityNestedOrderByQuery} asc;"); + var odataNestedOrderByQuery = odataQueryExpressionVisitor.GetODataQuery(); + + _queryBuilder.Append($"{Contants.QueryParameterOrderBy}{Contants.QueryStringEqualSign}{odataNestedOrderByQuery} {Contants.QuerySortAsc}{Contants.QueryStringNestedSeparator}"); return this; } public IODataQueryNestedParameter OrderByDescending(Expression> entityNestedOrderByDescending) { - var entityNestedOrderByDescendingQuery = entityNestedOrderByDescending.Body.ToODataQuery(string.Empty); + var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); + + odataQueryExpressionVisitor.Visit(entityNestedOrderByDescending.Body); + + var odataNestedOrderByDescendingQuery = odataQueryExpressionVisitor.GetODataQuery(); - _queryBuilder.Append($"$orderby={entityNestedOrderByDescendingQuery} desc;"); + _queryBuilder.Append($"{Contants.QueryParameterOrderBy}{Contants.QueryStringEqualSign}{odataNestedOrderByDescendingQuery} {Contants.QuerySortDesc}{Contants.QueryStringNestedSeparator}"); return this; } - public IODataQueryNestedParameter Select(Expression> entitySelectNested) + public IODataQueryNestedParameter Select(Expression> entityNestedSelect) { - var entitySelectNestedQuery = entitySelectNested.Body.ToODataQuery(string.Empty); + var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); + + odataQueryExpressionVisitor.Visit(entityNestedSelect.Body); + + var odataNestedSelectQuery = odataQueryExpressionVisitor.GetODataQuery(); - _queryBuilder.Append($"$select={entitySelectNestedQuery};"); + _queryBuilder.Append($"{Contants.QueryParameterSelect}{Contants.QueryStringEqualSign}{odataNestedSelectQuery}{Contants.QueryStringNestedSeparator}"); return this; } - public IODataQueryNestedParameter Top(int number) + public IODataQueryNestedParameter Top(int value) { - _queryBuilder.Append($"$top={number};"); + _queryBuilder.Append($"{Contants.QueryParameterTop}{Contants.QueryStringEqualSign}{value}{Contants.QueryStringNestedSeparator}"); return this; } diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs index 5ed7b581..65295838 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs @@ -8,6 +8,6 @@ public abstract class ODataQueryNestedParameterBase public ODataQueryNestedParameterBase() => _queryBuilder = new StringBuilder(); - public string Query => _queryBuilder.ToString().Trim(';'); + public string Query => _queryBuilder.ToString().Trim(Contants.QueryCharNestedSeparator); } } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs index ce05fa38..daabdd7f 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs @@ -1,5 +1,5 @@ using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.Extensions; +using OData.QueryBuilder.Expressions; using System; using System.Collections.Generic; using System.Linq.Expressions; @@ -16,45 +16,53 @@ public ODataQueryParameterKey(StringBuilder queryBuilder) => public IODataQueryParameterKey Expand(Expression> entityExpand) { - var entityExpandQuery = entityExpand.Body.ToODataQuery(string.Empty); + var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); - _queryBuilder.Append($"$expand={entityExpandQuery}&"); + odataQueryExpressionVisitor.Visit(entityExpand.Body); + + var odataExpandQuery = odataQueryExpressionVisitor.GetODataQuery(); + + _queryBuilder.Append($"{Contants.QueryParameterExpand}{Contants.QueryStringEqualSign}{odataExpandQuery}{Contants.QueryStringSeparator}"); return this; } - public IODataQueryParameterKey Expand(Action> entityExpandNested) + public IODataQueryParameterKey Expand(Action> actionEntityExpandNested) { var odataQueryNestedBuilder = new ODataQueryNestedBuilder(); - entityExpandNested(odataQueryNestedBuilder); + actionEntityExpandNested(odataQueryNestedBuilder); - _queryBuilder.Append($"$expand={odataQueryNestedBuilder.Query}&"); + _queryBuilder.Append($"{Contants.QueryParameterExpand}{Contants.QueryStringEqualSign}{odataQueryNestedBuilder.Query}{Contants.QueryStringSeparator}"); return this; } public IODataQueryParameterKey Select(Expression> entitySelect) { - var entitySelectQuery = entitySelect.Body.ToODataQuery(string.Empty); + var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); + + odataQueryExpressionVisitor.Visit(entitySelect.Body); + + var odataSelectQuery = odataQueryExpressionVisitor.GetODataQuery(); - _queryBuilder.Append($"$select={entitySelectQuery}&"); + _queryBuilder.Append($"{Contants.QueryParameterSelect}{Contants.QueryStringEqualSign}{odataSelectQuery}{Contants.QueryStringSeparator}"); return this; } - public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd('&')); + public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd(Contants.QueryCharSeparator)); public Dictionary ToDictionary() { var odataOperators = _queryBuilder.ToString() - .Split(new char[2] { '?', '&' }, StringSplitOptions.RemoveEmptyEntries); + .Split(new char[2] { Contants.QueryCharBegin, Contants.QueryCharSeparator }, StringSplitOptions.RemoveEmptyEntries); var dictionary = new Dictionary(odataOperators.Length - 1); for (var step = 1; step < odataOperators.Length; step++) { - var odataOperator = odataOperators[step].Split('='); + var odataOperator = odataOperators[step].Split(Contants.QueryCharEqualSign); dictionary.Add(odataOperator[0], odataOperator[1]); } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs index 9a71d9f3..95207bcb 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs @@ -1,5 +1,5 @@ using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.Extensions; +using OData.QueryBuilder.Expressions; using System; using System.Collections.Generic; using System.Linq.Expressions; @@ -16,18 +16,26 @@ public ODataQueryParameterList(StringBuilder queryBuilder) => public IODataQueryParameterList Filter(Expression> entityFilter) { - var entityFilterQuery = entityFilter.Body.ToODataQuery(string.Empty); + var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); - _queryBuilder.Append($"$filter={entityFilterQuery}&"); + odataQueryExpressionVisitor.Visit(entityFilter.Body); + + var odataFilterQuery = odataQueryExpressionVisitor.GetODataQuery(); + + _queryBuilder.Append($"{Contants.QueryParameterFilter}{Contants.QueryStringEqualSign}{odataFilterQuery}{Contants.QueryStringSeparator}"); return this; } public IODataQueryParameterList Expand(Expression> entityExpand) { - var entityExpandQuery = entityExpand.Body.ToODataQuery(string.Empty); + var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); + + odataQueryExpressionVisitor.Visit(entityExpand.Body); - _queryBuilder.Append($"$expand={entityExpandQuery}&"); + var odataExpandQuery = odataQueryExpressionVisitor.GetODataQuery(); + + _queryBuilder.Append($"{Contants.QueryParameterExpand}{Contants.QueryStringEqualSign}{odataExpandQuery}{Contants.QueryStringSeparator}"); return this; } @@ -38,71 +46,83 @@ public IODataQueryParameterList Expand(Action Select(Expression> entitySelect) { - var entitySelectQuery = entitySelect.Body.ToODataQuery(string.Empty); + var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); + + odataQueryExpressionVisitor.Visit(entitySelect.Body); - _queryBuilder.Append($"$select={entitySelectQuery}&"); + var odataSelectQuery = odataQueryExpressionVisitor.GetODataQuery(); + + _queryBuilder.Append($"{Contants.QueryParameterSelect}{Contants.QueryStringEqualSign}{odataSelectQuery}{Contants.QueryStringSeparator}"); return this; } public IODataQueryParameterList OrderBy(Expression> entityOrderBy) { - var entityOrderByQuery = entityOrderBy.Body.ToODataQuery(string.Empty); + var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); + + odataQueryExpressionVisitor.Visit(entityOrderBy.Body); + + var odataOrderByQuery = odataQueryExpressionVisitor.GetODataQuery(); - _queryBuilder.Append($"$orderby={entityOrderByQuery} asc&"); + _queryBuilder.Append($"{Contants.QueryParameterOrderBy}{Contants.QueryStringEqualSign}{odataOrderByQuery} {Contants.QuerySortAsc}{Contants.QueryStringSeparator}"); return this; } public IODataQueryParameterList OrderByDescending(Expression> entityOrderByDescending) { - var entityOrderByDescendingQuery = entityOrderByDescending.Body.ToODataQuery(string.Empty); + var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); + + odataQueryExpressionVisitor.Visit(entityOrderByDescending.Body); + + var odataOrderByDescendingQuery = odataQueryExpressionVisitor.GetODataQuery(); - _queryBuilder.Append($"$orderby={entityOrderByDescendingQuery} desc&"); + _queryBuilder.Append($"{Contants.QueryParameterOrderBy}{Contants.QueryStringEqualSign}{odataOrderByDescendingQuery} {Contants.QuerySortDesc}{Contants.QueryStringSeparator}"); return this; } - public IODataQueryParameterList Skip(int number) + public IODataQueryParameterList Skip(int value) { - _queryBuilder.Append($"$skip={number}&"); + _queryBuilder.Append($"{Contants.QueryParameterSkip}{Contants.QueryStringEqualSign}{value}{Contants.QueryStringSeparator}"); return this; } - public IODataQueryParameterList Top(int number) + public IODataQueryParameterList Top(int value) { - _queryBuilder.Append($"$top={number}&"); + _queryBuilder.Append($"{Contants.QueryParameterTop}{Contants.QueryStringEqualSign}{value}{Contants.QueryStringSeparator}"); return this; } public IODataQueryParameterList Count(bool value = true) { - _queryBuilder.Append($"$count={value.ToString().ToLower()}&"); + _queryBuilder.Append($"{Contants.QueryParameterCount}{Contants.QueryStringEqualSign}{value.ToString().ToLower()}{Contants.QueryStringSeparator}"); return this; } - public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd('&')); + public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd(Contants.QueryCharSeparator)); public Dictionary ToDictionary() { var odataOperators = _queryBuilder.ToString() - .Split(new char[2] { '?', '&' }, StringSplitOptions.RemoveEmptyEntries); + .Split(new char[2] { Contants.QueryCharBegin, Contants.QueryCharSeparator }, StringSplitOptions.RemoveEmptyEntries); var dictionary = new Dictionary(odataOperators.Length - 1); for (var step = 1; step < odataOperators.Length; step++) { - var odataOperator = odataOperators[step].Split('='); + var odataOperator = odataOperators[step].Split(Contants.QueryCharEqualSign); dictionary.Add(odataOperator[0], odataOperator[1]); } From 56b56ea8dd83482c755078571a1b4d007ac60b71 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Tue, 5 May 2020 18:08:26 +0300 Subject: [PATCH 03/76] #ZEXSM#fix --- .../ODataQueryExpressionVisitor.cs | 36 ++++++++++++++++--- .../Extensions/ExpressionExtension.cs | 22 ++++++------ .../Parameters/{Contants.cs => Constants.cs} | 5 ++- .../Nested/ODataQueryNestedParameter.cs | 14 ++++---- .../Nested/ODataQueryNestedParameterBase.cs | 2 +- .../Parameters/ODataQueryParameterKey.cs | 12 +++---- .../Parameters/ODataQueryParameterList.cs | 24 ++++++------- 7 files changed, 71 insertions(+), 44 deletions(-) rename src/OData.QueryBuilder/Parameters/{Contants.cs => Constants.cs} (84%) diff --git a/src/OData.QueryBuilder/Expressions/ODataQueryExpressionVisitor.cs b/src/OData.QueryBuilder/Expressions/ODataQueryExpressionVisitor.cs index ab4bb1f6..40004b95 100644 --- a/src/OData.QueryBuilder/Expressions/ODataQueryExpressionVisitor.cs +++ b/src/OData.QueryBuilder/Expressions/ODataQueryExpressionVisitor.cs @@ -1,4 +1,5 @@ using OData.QueryBuilder.Extensions; +using OData.QueryBuilder.Parameters; using System.Linq.Expressions; using System.Text; @@ -21,7 +22,13 @@ public override Expression Visit(Expression node) protected override Expression VisitBinary(BinaryExpression node) { - return base.VisitBinary(node); + Visit(node.Left); + + _queryBuilder.Append($" {node.GetODataLogicalOperator()} "); + + Visit(node.Right); + + return default; } protected override Expression VisitBlock(BlockExpression node) @@ -41,6 +48,25 @@ protected override Expression VisitConditional(ConditionalExpression node) protected override Expression VisitConstant(ConstantExpression node) { + switch (node.Value) + { + case bool b: + _queryBuilder.Append(b.ToString().ToLower()); + break; + case int i: + _queryBuilder.Append(i); + break; + case string s: + _queryBuilder.Append($"'{s}'"); + break; + case object o: + _queryBuilder.Append($"'{o}'"); + break; + default: + _queryBuilder.Append("null"); + break; + } + return base.VisitConstant(node); } @@ -101,7 +127,7 @@ protected override Expression VisitLoop(LoopExpression node) protected override Expression VisitMember(MemberExpression node) { - _queryBuilder.Append(node.Member.Name); + _queryBuilder.Append($"{node.Member.Name}"); return base.VisitMember(node); } @@ -144,7 +170,7 @@ protected override Expression VisitNew(NewExpression node) if (i != node.Arguments.Count - 1) { - _queryBuilder.Append(","); + _queryBuilder.Append(Constants.CommaStringSeparator); } } @@ -183,9 +209,9 @@ protected override Expression VisitTypeBinary(TypeBinaryExpression node) protected override Expression VisitUnary(UnaryExpression node) { - var odataLogicalOperator = node.GetODataLogicalOperator(); + //var odataLogicalOperator = node.GetODataLogicalOperator(); - _queryBuilder.Append(odataLogicalOperator); + //_queryBuilder.Append(odataLogicalOperator); return base.VisitUnary(node); } diff --git a/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs b/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs index 34da53d4..fb3edfab 100644 --- a/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs +++ b/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs @@ -7,32 +7,30 @@ namespace OData.QueryBuilder.Extensions { internal static class ExpressionExtension { - public static string GetODataLogicalOperator(this Expression expression, bool isSpaceToEnd = true) + public static string GetODataLogicalOperator(this Expression expression) { - var spaceEnd = isSpaceToEnd ? " " : string.Empty; - switch (expression.NodeType) { case ExpressionType.And: case ExpressionType.AndAlso: - return $"and{spaceEnd}"; + return $"and"; case ExpressionType.Or: case ExpressionType.OrElse: - return $"or{spaceEnd}"; + return $"or"; case ExpressionType.Equal: - return $"eq{spaceEnd}"; + return $"eq"; case ExpressionType.Not: - return $"not{spaceEnd}"; + return $"not"; case ExpressionType.NotEqual: - return $"ne{spaceEnd}"; + return $"ne"; case ExpressionType.LessThan: - return $"lt{spaceEnd}"; + return $"lt"; case ExpressionType.LessThanOrEqual: - return $"le{spaceEnd}"; + return $"le"; case ExpressionType.GreaterThan: - return $"gt{spaceEnd}"; + return $"gt"; case ExpressionType.GreaterThanOrEqual: - return $"ge{spaceEnd}"; + return $"ge"; default: return string.Empty; } diff --git a/src/OData.QueryBuilder/Parameters/Contants.cs b/src/OData.QueryBuilder/Parameters/Constants.cs similarity index 84% rename from src/OData.QueryBuilder/Parameters/Contants.cs rename to src/OData.QueryBuilder/Parameters/Constants.cs index 766eebe8..0edd0982 100644 --- a/src/OData.QueryBuilder/Parameters/Contants.cs +++ b/src/OData.QueryBuilder/Parameters/Constants.cs @@ -1,6 +1,6 @@ namespace OData.QueryBuilder.Parameters { - internal struct Contants + internal struct Constants { public const string QueryStringSeparator = "&"; public const char QueryCharSeparator = '&'; @@ -10,6 +10,9 @@ internal struct Contants public const char QueryCharBegin = '?'; public const string QueryStringEqualSign = "="; public const char QueryCharEqualSign = '='; + public const string SlashStringSeparator = "/"; + public const string CommaStringSeparator = ","; + public const char DotCharSeparator = '.'; public const string QueryParameterSelect = "$select"; public const string QueryParameterExpand = "$expand"; diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs index 52c5556a..56df8955 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs @@ -21,7 +21,7 @@ public IODataQueryNestedParameter Expand(Expression Expand(Action Filter(Expression var odataNestedFilterQuery = odataQueryExpressionVisitor.GetODataQuery(); - _queryBuilder.Append($"{Contants.QueryParameterFilter}{Contants.QueryStringEqualSign}{odataNestedFilterQuery}{Contants.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterFilter}{Constants.QueryStringEqualSign}{odataNestedFilterQuery}{Constants.QueryStringNestedSeparator}"); return this; } @@ -58,7 +58,7 @@ public IODataQueryNestedParameter OrderBy(Expression OrderByDescending(Expression Select(Expression Top(int value) { - _queryBuilder.Append($"{Contants.QueryParameterTop}{Contants.QueryStringEqualSign}{value}{Contants.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterTop}{Constants.QueryStringEqualSign}{value}{Constants.QueryStringNestedSeparator}"); return this; } diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs index 65295838..492f02ad 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs @@ -8,6 +8,6 @@ public abstract class ODataQueryNestedParameterBase public ODataQueryNestedParameterBase() => _queryBuilder = new StringBuilder(); - public string Query => _queryBuilder.ToString().Trim(Contants.QueryCharNestedSeparator); + public string Query => _queryBuilder.ToString().Trim(Constants.QueryCharNestedSeparator); } } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs index daabdd7f..fc2540fd 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs @@ -22,7 +22,7 @@ public IODataQueryParameterKey Expand(Expression> var odataExpandQuery = odataQueryExpressionVisitor.GetODataQuery(); - _queryBuilder.Append($"{Contants.QueryParameterExpand}{Contants.QueryStringEqualSign}{odataExpandQuery}{Contants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{odataExpandQuery}{Constants.QueryStringSeparator}"); return this; } @@ -33,7 +33,7 @@ public IODataQueryParameterKey Expand(Action Select(Expression> var odataSelectQuery = odataQueryExpressionVisitor.GetODataQuery(); - _queryBuilder.Append($"{Contants.QueryParameterSelect}{Contants.QueryStringEqualSign}{odataSelectQuery}{Contants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{odataSelectQuery}{Constants.QueryStringSeparator}"); return this; } - public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd(Contants.QueryCharSeparator)); + public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd(Constants.QueryCharSeparator)); public Dictionary ToDictionary() { var odataOperators = _queryBuilder.ToString() - .Split(new char[2] { Contants.QueryCharBegin, Contants.QueryCharSeparator }, StringSplitOptions.RemoveEmptyEntries); + .Split(new char[2] { Constants.QueryCharBegin, Constants.QueryCharSeparator }, StringSplitOptions.RemoveEmptyEntries); var dictionary = new Dictionary(odataOperators.Length - 1); for (var step = 1; step < odataOperators.Length; step++) { - var odataOperator = odataOperators[step].Split(Contants.QueryCharEqualSign); + var odataOperator = odataOperators[step].Split(Constants.QueryCharEqualSign); dictionary.Add(odataOperator[0], odataOperator[1]); } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs index 95207bcb..e6974840 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs @@ -22,7 +22,7 @@ public IODataQueryParameterList Filter(Expression> var odataFilterQuery = odataQueryExpressionVisitor.GetODataQuery(); - _queryBuilder.Append($"{Contants.QueryParameterFilter}{Contants.QueryStringEqualSign}{odataFilterQuery}{Contants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterFilter}{Constants.QueryStringEqualSign}{odataFilterQuery}{Constants.QueryStringSeparator}"); return this; } @@ -35,7 +35,7 @@ public IODataQueryParameterList Expand(Expression var odataExpandQuery = odataQueryExpressionVisitor.GetODataQuery(); - _queryBuilder.Append($"{Contants.QueryParameterExpand}{Contants.QueryStringEqualSign}{odataExpandQuery}{Contants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{odataExpandQuery}{Constants.QueryStringSeparator}"); return this; } @@ -46,7 +46,7 @@ public IODataQueryParameterList Expand(Action Select(Expression var odataSelectQuery = odataQueryExpressionVisitor.GetODataQuery(); - _queryBuilder.Append($"{Contants.QueryParameterSelect}{Contants.QueryStringEqualSign}{odataSelectQuery}{Contants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{odataSelectQuery}{Constants.QueryStringSeparator}"); return this; } @@ -72,7 +72,7 @@ public IODataQueryParameterList OrderBy(Expression OrderByDescending(Expression Skip(int value) { - _queryBuilder.Append($"{Contants.QueryParameterSkip}{Contants.QueryStringEqualSign}{value}{Contants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterSkip}{Constants.QueryStringEqualSign}{value}{Constants.QueryStringSeparator}"); return this; } public IODataQueryParameterList Top(int value) { - _queryBuilder.Append($"{Contants.QueryParameterTop}{Contants.QueryStringEqualSign}{value}{Contants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterTop}{Constants.QueryStringEqualSign}{value}{Constants.QueryStringSeparator}"); return this; } public IODataQueryParameterList Count(bool value = true) { - _queryBuilder.Append($"{Contants.QueryParameterCount}{Contants.QueryStringEqualSign}{value.ToString().ToLower()}{Contants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterCount}{Constants.QueryStringEqualSign}{value.ToString().ToLower()}{Constants.QueryStringSeparator}"); return this; } - public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd(Contants.QueryCharSeparator)); + public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd(Constants.QueryCharSeparator)); public Dictionary ToDictionary() { var odataOperators = _queryBuilder.ToString() - .Split(new char[2] { Contants.QueryCharBegin, Contants.QueryCharSeparator }, StringSplitOptions.RemoveEmptyEntries); + .Split(new char[2] { Constants.QueryCharBegin, Constants.QueryCharSeparator }, StringSplitOptions.RemoveEmptyEntries); var dictionary = new Dictionary(odataOperators.Length - 1); for (var step = 1; step < odataOperators.Length; step++) { - var odataOperator = odataOperators[step].Split(Contants.QueryCharEqualSign); + var odataOperator = odataOperators[step].Split(Constants.QueryCharEqualSign); dictionary.Add(odataOperator[0], odataOperator[1]); } From 801881c149cab9318372e01dd1dcd5edebb0ef1b Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Tue, 5 May 2020 22:44:33 +0300 Subject: [PATCH 04/76] #ZEXSM#Decomposition visitors --- .../Builders/ODataQueryBuilder.cs | 15 +- .../ExpandODataExpressionVisitor.cs | 28 +++ .../FilterODataExpressionVisitor.cs | 68 ++++++ .../ODataExpressionVisitor.cs | 23 ++ .../OrderByODataExpressionVisitor.cs | 28 +++ .../SelectODataExpressionVisitor.cs | 28 +++ .../ODataQueryExpressionVisitor.cs | 219 ------------------ .../Parameters/Constants.cs | 1 + .../Nested/ODataQueryNestedParameter.cs | 49 ++-- .../Parameters/ODataQueryParameterKey.cs | 24 +- .../Parameters/ODataQueryParameterList.cs | 48 ++-- .../Resourses/ODataQueryResource.cs | 6 +- 12 files changed, 235 insertions(+), 302 deletions(-) create mode 100644 src/OData.QueryBuilder/ExpressionVisitors/ExpandODataExpressionVisitor.cs create mode 100644 src/OData.QueryBuilder/ExpressionVisitors/FilterODataExpressionVisitor.cs create mode 100644 src/OData.QueryBuilder/ExpressionVisitors/ODataExpressionVisitor.cs create mode 100644 src/OData.QueryBuilder/ExpressionVisitors/OrderByODataExpressionVisitor.cs create mode 100644 src/OData.QueryBuilder/ExpressionVisitors/SelectODataExpressionVisitor.cs delete mode 100644 src/OData.QueryBuilder/Expressions/ODataQueryExpressionVisitor.cs diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index 025478f1..185e8bb7 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -1,4 +1,5 @@ -using OData.QueryBuilder.Expressions; +using OData.QueryBuilder.ExpressionVisitors; +using OData.QueryBuilder.Parameters; using OData.QueryBuilder.Resourses; using System; using System.Linq.Expressions; @@ -10,18 +11,18 @@ public class ODataQueryBuilder : IODataQueryBuilder private readonly string _baseUrl; public ODataQueryBuilder(Uri baseUrl) => - _baseUrl = $"{baseUrl.OriginalString.TrimEnd('/')}/"; + _baseUrl = $"{baseUrl.OriginalString.TrimEnd(Constants.SlashCharSeparator)}{Constants.SlashStringSeparator}"; public ODataQueryBuilder(string baseUrl) => - _baseUrl = $"{baseUrl.TrimEnd('/')}/"; + _baseUrl = $"{baseUrl.TrimEnd(Constants.SlashCharSeparator)}{Constants.SlashStringSeparator}"; public IODataQueryResource For(Expression> entityResource) { - var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); - odataQueryExpressionVisitor.Visit(entityResource.Body); - var odataResourceQuery = odataQueryExpressionVisitor.GetODataQuery(); + var visitor = new ODataExpressionVisitor(); - return new ODataQueryResource($"{_baseUrl}{odataResourceQuery}"); + visitor.Visit(entityResource.Body); + + return new ODataQueryResource($"{_baseUrl}{visitor.Query}"); } } } \ No newline at end of file diff --git a/src/OData.QueryBuilder/ExpressionVisitors/ExpandODataExpressionVisitor.cs b/src/OData.QueryBuilder/ExpressionVisitors/ExpandODataExpressionVisitor.cs new file mode 100644 index 00000000..a3aa59fb --- /dev/null +++ b/src/OData.QueryBuilder/ExpressionVisitors/ExpandODataExpressionVisitor.cs @@ -0,0 +1,28 @@ +using OData.QueryBuilder.Parameters; +using System.Linq.Expressions; + +namespace OData.QueryBuilder.ExpressionVisitors +{ + internal class ExpandODataExpressionVisitor : ODataExpressionVisitor + { + private int _count; + + public ExpandODataExpressionVisitor() + : base() + { + _count = default; + } + + protected override Expression VisitMember(MemberExpression node) + { + if (_count != default) + { + _queryBuilder.Append(Constants.CommaStringSeparator); + } + + _count++; + + return base.VisitMember(node); + } + } +} diff --git a/src/OData.QueryBuilder/ExpressionVisitors/FilterODataExpressionVisitor.cs b/src/OData.QueryBuilder/ExpressionVisitors/FilterODataExpressionVisitor.cs new file mode 100644 index 00000000..671cb2ef --- /dev/null +++ b/src/OData.QueryBuilder/ExpressionVisitors/FilterODataExpressionVisitor.cs @@ -0,0 +1,68 @@ +using OData.QueryBuilder.Extensions; +using System.Linq.Expressions; + +namespace OData.QueryBuilder.ExpressionVisitors +{ + internal class FilterODataExpressionVisitor : ODataExpressionVisitor + { + public FilterODataExpressionVisitor() + : base() + { + } + + protected override Expression VisitBinary(BinaryExpression node) + { + Visit(node.Left); + + _queryBuilder.Append($" {node.GetODataLogicalOperator()} "); + + Visit(node.Right); + + return default; + } + + protected override Expression VisitConstant(ConstantExpression node) + { + switch (node.Value) + { + case bool b: + _queryBuilder.Append(b.ToString().ToLower()); + break; + case int i: + _queryBuilder.Append(i); + break; + case string s: + _queryBuilder.Append($"'{s}'"); + break; + case object o: + _queryBuilder.Append($"'{o}'"); + break; + default: + _queryBuilder.Append("null"); + break; + } + + return base.VisitConstant(node); + } + + protected override Expression VisitLambda(Expression node) + { + return base.VisitLambda(node); + } + + protected override Expression VisitMember(MemberExpression node) + { + return base.VisitMember(node); + } + + protected override Expression VisitMethodCall(MethodCallExpression node) + { + return base.VisitMethodCall(node); + } + + protected override Expression VisitParameter(ParameterExpression node) + { + return base.VisitParameter(node); + } + } +} diff --git a/src/OData.QueryBuilder/ExpressionVisitors/ODataExpressionVisitor.cs b/src/OData.QueryBuilder/ExpressionVisitors/ODataExpressionVisitor.cs new file mode 100644 index 00000000..6f458e9c --- /dev/null +++ b/src/OData.QueryBuilder/ExpressionVisitors/ODataExpressionVisitor.cs @@ -0,0 +1,23 @@ +using System.Linq.Expressions; +using System.Text; + +namespace OData.QueryBuilder.ExpressionVisitors +{ + internal class ODataExpressionVisitor : ExpressionVisitor + { + protected StringBuilder _queryBuilder; + + public ODataExpressionVisitor() + : base() => + _queryBuilder = new StringBuilder(); + + public string Query => _queryBuilder.ToString(); + + protected override Expression VisitMember(MemberExpression node) + { + _queryBuilder.Append($"{node.Member.Name}"); + + return base.VisitMember(node); + } + } +} diff --git a/src/OData.QueryBuilder/ExpressionVisitors/OrderByODataExpressionVisitor.cs b/src/OData.QueryBuilder/ExpressionVisitors/OrderByODataExpressionVisitor.cs new file mode 100644 index 00000000..9f5da124 --- /dev/null +++ b/src/OData.QueryBuilder/ExpressionVisitors/OrderByODataExpressionVisitor.cs @@ -0,0 +1,28 @@ +using OData.QueryBuilder.Parameters; +using System.Linq.Expressions; + +namespace OData.QueryBuilder.ExpressionVisitors +{ + internal class OrderByODataExpressionVisitor : ODataExpressionVisitor + { + private int _count; + + public OrderByODataExpressionVisitor() + : base() + { + _count = default; + } + + protected override Expression VisitMember(MemberExpression node) + { + if (_count != default) + { + _queryBuilder.Append(Constants.CommaStringSeparator); + } + + _count++; + + return base.VisitMember(node); + } + } +} diff --git a/src/OData.QueryBuilder/ExpressionVisitors/SelectODataExpressionVisitor.cs b/src/OData.QueryBuilder/ExpressionVisitors/SelectODataExpressionVisitor.cs new file mode 100644 index 00000000..0fc0eda5 --- /dev/null +++ b/src/OData.QueryBuilder/ExpressionVisitors/SelectODataExpressionVisitor.cs @@ -0,0 +1,28 @@ +using OData.QueryBuilder.Parameters; +using System.Linq.Expressions; + +namespace OData.QueryBuilder.ExpressionVisitors +{ + internal class SelectODataExpressionVisitor : ODataExpressionVisitor + { + private int _count; + + public SelectODataExpressionVisitor() + : base() + { + _count = default; + } + + protected override Expression VisitMember(MemberExpression node) + { + if (_count != default) + { + _queryBuilder.Append(Constants.CommaStringSeparator); + } + + _count++; + + return base.VisitMember(node); + } + } +} diff --git a/src/OData.QueryBuilder/Expressions/ODataQueryExpressionVisitor.cs b/src/OData.QueryBuilder/Expressions/ODataQueryExpressionVisitor.cs deleted file mode 100644 index 40004b95..00000000 --- a/src/OData.QueryBuilder/Expressions/ODataQueryExpressionVisitor.cs +++ /dev/null @@ -1,219 +0,0 @@ -using OData.QueryBuilder.Extensions; -using OData.QueryBuilder.Parameters; -using System.Linq.Expressions; -using System.Text; - -namespace OData.QueryBuilder.Expressions -{ - internal class ODataQueryExpressionVisitor : ExpressionVisitor - { - private readonly StringBuilder _queryBuilder; - - public ODataQueryExpressionVisitor() - : base() => - _queryBuilder = new StringBuilder(); - - public string GetODataQuery() => _queryBuilder.ToString(); - - public override Expression Visit(Expression node) - { - return base.Visit(node); - } - - protected override Expression VisitBinary(BinaryExpression node) - { - Visit(node.Left); - - _queryBuilder.Append($" {node.GetODataLogicalOperator()} "); - - Visit(node.Right); - - return default; - } - - protected override Expression VisitBlock(BlockExpression node) - { - return base.VisitBlock(node); - } - - protected override CatchBlock VisitCatchBlock(CatchBlock node) - { - return base.VisitCatchBlock(node); - } - - protected override Expression VisitConditional(ConditionalExpression node) - { - return base.VisitConditional(node); - } - - protected override Expression VisitConstant(ConstantExpression node) - { - switch (node.Value) - { - case bool b: - _queryBuilder.Append(b.ToString().ToLower()); - break; - case int i: - _queryBuilder.Append(i); - break; - case string s: - _queryBuilder.Append($"'{s}'"); - break; - case object o: - _queryBuilder.Append($"'{o}'"); - break; - default: - _queryBuilder.Append("null"); - break; - } - - return base.VisitConstant(node); - } - - protected override Expression VisitDefault(DefaultExpression node) - { - return base.VisitDefault(node); - } - - protected override ElementInit VisitElementInit(ElementInit node) - { - return base.VisitElementInit(node); - } - - protected override Expression VisitExtension(Expression node) - { - return base.VisitExtension(node); - } - - protected override Expression VisitGoto(GotoExpression node) - { - return base.VisitGoto(node); - } - - protected override Expression VisitIndex(IndexExpression node) - { - return base.VisitIndex(node); - } - - protected override Expression VisitInvocation(InvocationExpression node) - { - return base.VisitInvocation(node); - } - - protected override Expression VisitLabel(LabelExpression node) - { - return base.VisitLabel(node); - } - - protected override LabelTarget VisitLabelTarget(LabelTarget node) - { - return base.VisitLabelTarget(node); - } - - protected override Expression VisitLambda(Expression node) - { - return base.VisitLambda(node); - } - - protected override Expression VisitListInit(ListInitExpression node) - { - return base.VisitListInit(node); - } - - protected override Expression VisitLoop(LoopExpression node) - { - return base.VisitLoop(node); - } - - protected override Expression VisitMember(MemberExpression node) - { - _queryBuilder.Append($"{node.Member.Name}"); - - return base.VisitMember(node); - } - - protected override MemberAssignment VisitMemberAssignment(MemberAssignment node) - { - return base.VisitMemberAssignment(node); - } - - protected override MemberBinding VisitMemberBinding(MemberBinding node) - { - return base.VisitMemberBinding(node); - } - - protected override Expression VisitMemberInit(MemberInitExpression node) - { - return base.VisitMemberInit(node); - } - - protected override MemberListBinding VisitMemberListBinding(MemberListBinding node) - { - return base.VisitMemberListBinding(node); - } - - protected override MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding node) - { - return base.VisitMemberMemberBinding(node); - } - - protected override Expression VisitMethodCall(MethodCallExpression node) - { - return base.VisitMethodCall(node); - } - - protected override Expression VisitNew(NewExpression node) - { - for (var i = 0; i < node.Arguments.Count; i++) - { - Visit(node.Arguments[i]); - - if (i != node.Arguments.Count - 1) - { - _queryBuilder.Append(Constants.CommaStringSeparator); - } - } - - return default; - } - - protected override Expression VisitNewArray(NewArrayExpression node) - { - return base.VisitNewArray(node); - } - - protected override Expression VisitParameter(ParameterExpression node) - { - return base.VisitParameter(node); - } - - protected override Expression VisitSwitch(SwitchExpression node) - { - return base.VisitSwitch(node); - } - - protected override SwitchCase VisitSwitchCase(SwitchCase node) - { - return base.VisitSwitchCase(node); - } - - protected override Expression VisitTry(TryExpression node) - { - return base.VisitTry(node); - } - - protected override Expression VisitTypeBinary(TypeBinaryExpression node) - { - return base.VisitTypeBinary(node); - } - - protected override Expression VisitUnary(UnaryExpression node) - { - //var odataLogicalOperator = node.GetODataLogicalOperator(); - - //_queryBuilder.Append(odataLogicalOperator); - - return base.VisitUnary(node); - } - } -} diff --git a/src/OData.QueryBuilder/Parameters/Constants.cs b/src/OData.QueryBuilder/Parameters/Constants.cs index 0edd0982..68dc4563 100644 --- a/src/OData.QueryBuilder/Parameters/Constants.cs +++ b/src/OData.QueryBuilder/Parameters/Constants.cs @@ -11,6 +11,7 @@ internal struct Constants public const string QueryStringEqualSign = "="; public const char QueryCharEqualSign = '='; public const string SlashStringSeparator = "/"; + public const char SlashCharSeparator = '/'; public const string CommaStringSeparator = ","; public const char DotCharSeparator = '.'; diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs index 56df8955..8a0bfa60 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs @@ -1,6 +1,5 @@ using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.Expressions; -using OData.QueryBuilder.Extensions; +using OData.QueryBuilder.ExpressionVisitors; using System; using System.Linq.Expressions; @@ -15,76 +14,66 @@ public ODataQueryNestedParameter() public IODataQueryNestedParameter Expand(Expression> entityNestedExpand) { - var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); + var visitor = new ExpandODataExpressionVisitor(); - odataQueryExpressionVisitor.Visit(entityNestedExpand.Body); + visitor.Visit(entityNestedExpand.Body); - var odataNestedExpandQuery = odataQueryExpressionVisitor.GetODataQuery(); - - _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{odataNestedExpandQuery}{Constants.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringNestedSeparator}"); return this; } public IODataQueryNestedParameter Expand(Action> actionEntityExpandNested) { - var odataQueryNestedBuilder = new ODataQueryNestedBuilder(); + var builder = new ODataQueryNestedBuilder(); - actionEntityExpandNested(odataQueryNestedBuilder); + actionEntityExpandNested(builder); - _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{odataQueryNestedBuilder.Query}{Constants.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{builder.Query}{Constants.QueryStringNestedSeparator}"); return this; } public IODataQueryNestedParameter Filter(Expression> entityNestedFilter) { - var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); - - odataQueryExpressionVisitor.Visit(entityNestedFilter.Body); + var visitor = new FilterODataExpressionVisitor(); - var odataNestedFilterQuery = odataQueryExpressionVisitor.GetODataQuery(); + visitor.Visit(entityNestedFilter.Body); - _queryBuilder.Append($"{Constants.QueryParameterFilter}{Constants.QueryStringEqualSign}{odataNestedFilterQuery}{Constants.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterFilter}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringNestedSeparator}"); return this; } public IODataQueryNestedParameter OrderBy(Expression> entityNestedOrderBy) { - var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); - - odataQueryExpressionVisitor.Visit(entityNestedOrderBy.Body); + var visitor = new OrderByODataExpressionVisitor(); - var odataNestedOrderByQuery = odataQueryExpressionVisitor.GetODataQuery(); + visitor.Visit(entityNestedOrderBy.Body); - _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{odataNestedOrderByQuery} {Constants.QuerySortAsc}{Constants.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{visitor.Query} {Constants.QuerySortAsc}{Constants.QueryStringNestedSeparator}"); return this; } public IODataQueryNestedParameter OrderByDescending(Expression> entityNestedOrderByDescending) { - var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); + var visitor = new OrderByODataExpressionVisitor(); - odataQueryExpressionVisitor.Visit(entityNestedOrderByDescending.Body); + visitor.Visit(entityNestedOrderByDescending.Body); - var odataNestedOrderByDescendingQuery = odataQueryExpressionVisitor.GetODataQuery(); - - _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{odataNestedOrderByDescendingQuery} {Constants.QuerySortDesc}{Constants.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{visitor.Query} {Constants.QuerySortDesc}{Constants.QueryStringNestedSeparator}"); return this; } public IODataQueryNestedParameter Select(Expression> entityNestedSelect) { - var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); - - odataQueryExpressionVisitor.Visit(entityNestedSelect.Body); + var visitor = new SelectODataExpressionVisitor(); - var odataNestedSelectQuery = odataQueryExpressionVisitor.GetODataQuery(); + visitor.Visit(entityNestedSelect.Body); - _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{odataNestedSelectQuery}{Constants.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringNestedSeparator}"); return this; } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs index fc2540fd..42e53236 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs @@ -1,5 +1,5 @@ using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.Expressions; +using OData.QueryBuilder.ExpressionVisitors; using System; using System.Collections.Generic; using System.Linq.Expressions; @@ -16,37 +16,33 @@ public ODataQueryParameterKey(StringBuilder queryBuilder) => public IODataQueryParameterKey Expand(Expression> entityExpand) { - var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); + var visitor = new ExpandODataExpressionVisitor(); - odataQueryExpressionVisitor.Visit(entityExpand.Body); + visitor.Visit(entityExpand.Body); - var odataExpandQuery = odataQueryExpressionVisitor.GetODataQuery(); - - _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{odataExpandQuery}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringSeparator}"); return this; } public IODataQueryParameterKey Expand(Action> actionEntityExpandNested) { - var odataQueryNestedBuilder = new ODataQueryNestedBuilder(); + var builder = new ODataQueryNestedBuilder(); - actionEntityExpandNested(odataQueryNestedBuilder); + actionEntityExpandNested(builder); - _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{odataQueryNestedBuilder.Query}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{builder.Query}{Constants.QueryStringSeparator}"); return this; } public IODataQueryParameterKey Select(Expression> entitySelect) { - var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); - - odataQueryExpressionVisitor.Visit(entitySelect.Body); + var visitor = new SelectODataExpressionVisitor(); - var odataSelectQuery = odataQueryExpressionVisitor.GetODataQuery(); + visitor.Visit(entitySelect.Body); - _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{odataSelectQuery}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringSeparator}"); return this; } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs index e6974840..8023d26f 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs @@ -1,5 +1,5 @@ using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.Expressions; +using OData.QueryBuilder.ExpressionVisitors; using System; using System.Collections.Generic; using System.Linq.Expressions; @@ -16,76 +16,66 @@ public ODataQueryParameterList(StringBuilder queryBuilder) => public IODataQueryParameterList Filter(Expression> entityFilter) { - var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); + var visitor = new FilterODataExpressionVisitor(); - odataQueryExpressionVisitor.Visit(entityFilter.Body); + visitor.Visit(entityFilter.Body); - var odataFilterQuery = odataQueryExpressionVisitor.GetODataQuery(); - - _queryBuilder.Append($"{Constants.QueryParameterFilter}{Constants.QueryStringEqualSign}{odataFilterQuery}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterFilter}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringSeparator}"); return this; } public IODataQueryParameterList Expand(Expression> entityExpand) { - var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); - - odataQueryExpressionVisitor.Visit(entityExpand.Body); + var visitor = new ExpandODataExpressionVisitor(); - var odataExpandQuery = odataQueryExpressionVisitor.GetODataQuery(); + visitor.Visit(entityExpand.Body); - _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{odataExpandQuery}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringSeparator}"); return this; } public IODataQueryParameterList Expand(Action> entityExpandNested) { - var odataQueryNestedBuilder = new ODataQueryNestedBuilder(); + var builder = new ODataQueryNestedBuilder(); - entityExpandNested(odataQueryNestedBuilder); + entityExpandNested(builder); - _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{odataQueryNestedBuilder.Query}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{builder.Query}{Constants.QueryStringSeparator}"); return this; } public IODataQueryParameterList Select(Expression> entitySelect) { - var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); - - odataQueryExpressionVisitor.Visit(entitySelect.Body); + var visitor = new SelectODataExpressionVisitor(); - var odataSelectQuery = odataQueryExpressionVisitor.GetODataQuery(); + visitor.Visit(entitySelect.Body); - _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{odataSelectQuery}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringSeparator}"); return this; } public IODataQueryParameterList OrderBy(Expression> entityOrderBy) { - var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); + var visitor = new OrderByODataExpressionVisitor(); - odataQueryExpressionVisitor.Visit(entityOrderBy.Body); + visitor.Visit(entityOrderBy.Body); - var odataOrderByQuery = odataQueryExpressionVisitor.GetODataQuery(); - - _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{odataOrderByQuery} {Constants.QuerySortAsc}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{visitor.Query} {Constants.QuerySortAsc}{Constants.QueryStringSeparator}"); return this; } public IODataQueryParameterList OrderByDescending(Expression> entityOrderByDescending) { - var odataQueryExpressionVisitor = new ODataQueryExpressionVisitor(); - - odataQueryExpressionVisitor.Visit(entityOrderByDescending.Body); + var visitor = new OrderByODataExpressionVisitor(); - var odataOrderByDescendingQuery = odataQueryExpressionVisitor.GetODataQuery(); + visitor.Visit(entityOrderByDescending.Body); - _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{odataOrderByDescendingQuery} {Constants.QuerySortDesc}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{visitor.Query} {Constants.QuerySortDesc}{Constants.QueryStringSeparator}"); return this; } diff --git a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs b/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs index 5ec0b8cf..02b806c7 100644 --- a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs +++ b/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs @@ -12,21 +12,21 @@ public ODataQueryResource(string resourceUrl) => public IODataQueryParameterKey ByKey(int key) { - _queryBuilder.Append($"({key})?"); + _queryBuilder.Append($"({key}){Constants.QueryStringBegin}"); return new ODataQueryParameterKey(_queryBuilder); } public IODataQueryParameterKey ByKey(string key) { - _queryBuilder.Append($"('{key}')?"); + _queryBuilder.Append($"('{key}'){Constants.QueryStringBegin}"); return new ODataQueryParameterKey(_queryBuilder); } public IODataQueryParameterList ByList() { - _queryBuilder.Append("?"); + _queryBuilder.Append(Constants.QueryStringBegin); return new ODataQueryParameterList(_queryBuilder); } From 00567eda53fec2dc465566adb598767591c85478 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sat, 9 May 2020 15:21:27 +0300 Subject: [PATCH 05/76] #ZEXSM#fix --- .../ExpressionVisitors/FilterODataExpressionVisitor.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/OData.QueryBuilder/ExpressionVisitors/FilterODataExpressionVisitor.cs b/src/OData.QueryBuilder/ExpressionVisitors/FilterODataExpressionVisitor.cs index 671cb2ef..611dd45f 100644 --- a/src/OData.QueryBuilder/ExpressionVisitors/FilterODataExpressionVisitor.cs +++ b/src/OData.QueryBuilder/ExpressionVisitors/FilterODataExpressionVisitor.cs @@ -1,4 +1,5 @@ using OData.QueryBuilder.Extensions; +using OData.QueryBuilder.Parameters; using System.Linq.Expressions; namespace OData.QueryBuilder.ExpressionVisitors @@ -45,13 +46,9 @@ protected override Expression VisitConstant(ConstantExpression node) return base.VisitConstant(node); } - protected override Expression VisitLambda(Expression node) - { - return base.VisitLambda(node); - } - protected override Expression VisitMember(MemberExpression node) { + _queryBuilder.Append(Constants.SlashStringSeparator); return base.VisitMember(node); } From 77c6b85d56015754ae605c23f1428c068d4f4d5e Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sat, 9 May 2020 15:58:20 +0300 Subject: [PATCH 06/76] #ZEXSM#fix --- .../Builders/ODataQueryBuilder.cs | 12 +--- .../ExpandODataExpressionVisitor.cs | 28 -------- .../FilterODataExpressionVisitor.cs | 65 ------------------- .../ODataExpressionVisitor.cs | 23 ------- .../OrderByODataExpressionVisitor.cs | 28 -------- .../SelectODataExpressionVisitor.cs | 28 -------- .../Nested/ODataQueryNestedParameter.cs | 32 ++++----- .../Parameters/ODataQueryParameterKey.cs | 14 ++-- .../Parameters/ODataQueryParameterList.cs | 32 ++++----- 9 files changed, 30 insertions(+), 232 deletions(-) delete mode 100644 src/OData.QueryBuilder/ExpressionVisitors/ExpandODataExpressionVisitor.cs delete mode 100644 src/OData.QueryBuilder/ExpressionVisitors/FilterODataExpressionVisitor.cs delete mode 100644 src/OData.QueryBuilder/ExpressionVisitors/ODataExpressionVisitor.cs delete mode 100644 src/OData.QueryBuilder/ExpressionVisitors/OrderByODataExpressionVisitor.cs delete mode 100644 src/OData.QueryBuilder/ExpressionVisitors/SelectODataExpressionVisitor.cs diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index 185e8bb7..b9d5f87b 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.ExpressionVisitors; +using OData.QueryBuilder.Extensions; using OData.QueryBuilder.Parameters; using OData.QueryBuilder.Resourses; using System; @@ -16,13 +16,7 @@ public ODataQueryBuilder(Uri baseUrl) => public ODataQueryBuilder(string baseUrl) => _baseUrl = $"{baseUrl.TrimEnd(Constants.SlashCharSeparator)}{Constants.SlashStringSeparator}"; - public IODataQueryResource For(Expression> entityResource) - { - var visitor = new ODataExpressionVisitor(); - - visitor.Visit(entityResource.Body); - - return new ODataQueryResource($"{_baseUrl}{visitor.Query}"); - } + public IODataQueryResource For(Expression> entityResource) => + new ODataQueryResource($"{_baseUrl}{entityResource.Body.ToODataQuery(string.Empty)}"); } } \ No newline at end of file diff --git a/src/OData.QueryBuilder/ExpressionVisitors/ExpandODataExpressionVisitor.cs b/src/OData.QueryBuilder/ExpressionVisitors/ExpandODataExpressionVisitor.cs deleted file mode 100644 index a3aa59fb..00000000 --- a/src/OData.QueryBuilder/ExpressionVisitors/ExpandODataExpressionVisitor.cs +++ /dev/null @@ -1,28 +0,0 @@ -using OData.QueryBuilder.Parameters; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.ExpressionVisitors -{ - internal class ExpandODataExpressionVisitor : ODataExpressionVisitor - { - private int _count; - - public ExpandODataExpressionVisitor() - : base() - { - _count = default; - } - - protected override Expression VisitMember(MemberExpression node) - { - if (_count != default) - { - _queryBuilder.Append(Constants.CommaStringSeparator); - } - - _count++; - - return base.VisitMember(node); - } - } -} diff --git a/src/OData.QueryBuilder/ExpressionVisitors/FilterODataExpressionVisitor.cs b/src/OData.QueryBuilder/ExpressionVisitors/FilterODataExpressionVisitor.cs deleted file mode 100644 index 611dd45f..00000000 --- a/src/OData.QueryBuilder/ExpressionVisitors/FilterODataExpressionVisitor.cs +++ /dev/null @@ -1,65 +0,0 @@ -using OData.QueryBuilder.Extensions; -using OData.QueryBuilder.Parameters; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.ExpressionVisitors -{ - internal class FilterODataExpressionVisitor : ODataExpressionVisitor - { - public FilterODataExpressionVisitor() - : base() - { - } - - protected override Expression VisitBinary(BinaryExpression node) - { - Visit(node.Left); - - _queryBuilder.Append($" {node.GetODataLogicalOperator()} "); - - Visit(node.Right); - - return default; - } - - protected override Expression VisitConstant(ConstantExpression node) - { - switch (node.Value) - { - case bool b: - _queryBuilder.Append(b.ToString().ToLower()); - break; - case int i: - _queryBuilder.Append(i); - break; - case string s: - _queryBuilder.Append($"'{s}'"); - break; - case object o: - _queryBuilder.Append($"'{o}'"); - break; - default: - _queryBuilder.Append("null"); - break; - } - - return base.VisitConstant(node); - } - - protected override Expression VisitMember(MemberExpression node) - { - _queryBuilder.Append(Constants.SlashStringSeparator); - return base.VisitMember(node); - } - - protected override Expression VisitMethodCall(MethodCallExpression node) - { - return base.VisitMethodCall(node); - } - - protected override Expression VisitParameter(ParameterExpression node) - { - return base.VisitParameter(node); - } - } -} diff --git a/src/OData.QueryBuilder/ExpressionVisitors/ODataExpressionVisitor.cs b/src/OData.QueryBuilder/ExpressionVisitors/ODataExpressionVisitor.cs deleted file mode 100644 index 6f458e9c..00000000 --- a/src/OData.QueryBuilder/ExpressionVisitors/ODataExpressionVisitor.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Linq.Expressions; -using System.Text; - -namespace OData.QueryBuilder.ExpressionVisitors -{ - internal class ODataExpressionVisitor : ExpressionVisitor - { - protected StringBuilder _queryBuilder; - - public ODataExpressionVisitor() - : base() => - _queryBuilder = new StringBuilder(); - - public string Query => _queryBuilder.ToString(); - - protected override Expression VisitMember(MemberExpression node) - { - _queryBuilder.Append($"{node.Member.Name}"); - - return base.VisitMember(node); - } - } -} diff --git a/src/OData.QueryBuilder/ExpressionVisitors/OrderByODataExpressionVisitor.cs b/src/OData.QueryBuilder/ExpressionVisitors/OrderByODataExpressionVisitor.cs deleted file mode 100644 index 9f5da124..00000000 --- a/src/OData.QueryBuilder/ExpressionVisitors/OrderByODataExpressionVisitor.cs +++ /dev/null @@ -1,28 +0,0 @@ -using OData.QueryBuilder.Parameters; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.ExpressionVisitors -{ - internal class OrderByODataExpressionVisitor : ODataExpressionVisitor - { - private int _count; - - public OrderByODataExpressionVisitor() - : base() - { - _count = default; - } - - protected override Expression VisitMember(MemberExpression node) - { - if (_count != default) - { - _queryBuilder.Append(Constants.CommaStringSeparator); - } - - _count++; - - return base.VisitMember(node); - } - } -} diff --git a/src/OData.QueryBuilder/ExpressionVisitors/SelectODataExpressionVisitor.cs b/src/OData.QueryBuilder/ExpressionVisitors/SelectODataExpressionVisitor.cs deleted file mode 100644 index 0fc0eda5..00000000 --- a/src/OData.QueryBuilder/ExpressionVisitors/SelectODataExpressionVisitor.cs +++ /dev/null @@ -1,28 +0,0 @@ -using OData.QueryBuilder.Parameters; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.ExpressionVisitors -{ - internal class SelectODataExpressionVisitor : ODataExpressionVisitor - { - private int _count; - - public SelectODataExpressionVisitor() - : base() - { - _count = default; - } - - protected override Expression VisitMember(MemberExpression node) - { - if (_count != default) - { - _queryBuilder.Append(Constants.CommaStringSeparator); - } - - _count++; - - return base.VisitMember(node); - } - } -} diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs index 8a0bfa60..41dedc45 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs @@ -1,5 +1,5 @@ using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.ExpressionVisitors; +using OData.QueryBuilder.Extensions; using System; using System.Linq.Expressions; @@ -14,11 +14,9 @@ public ODataQueryNestedParameter() public IODataQueryNestedParameter Expand(Expression> entityNestedExpand) { - var visitor = new ExpandODataExpressionVisitor(); + var query = entityNestedExpand.Body.ToODataQuery(string.Empty); - visitor.Visit(entityNestedExpand.Body); - - _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{query}{Constants.QueryStringNestedSeparator}"); return this; } @@ -36,44 +34,36 @@ public IODataQueryNestedParameter Expand(Action Filter(Expression> entityNestedFilter) { - var visitor = new FilterODataExpressionVisitor(); - - visitor.Visit(entityNestedFilter.Body); + var query = entityNestedFilter.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{Constants.QueryParameterFilter}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterFilter}{Constants.QueryStringEqualSign}{query}{Constants.QueryStringNestedSeparator}"); return this; } public IODataQueryNestedParameter OrderBy(Expression> entityNestedOrderBy) { - var visitor = new OrderByODataExpressionVisitor(); - - visitor.Visit(entityNestedOrderBy.Body); + var query = entityNestedOrderBy.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{visitor.Query} {Constants.QuerySortAsc}{Constants.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{query} {Constants.QuerySortAsc}{Constants.QueryStringNestedSeparator}"); return this; } public IODataQueryNestedParameter OrderByDescending(Expression> entityNestedOrderByDescending) { - var visitor = new OrderByODataExpressionVisitor(); + var query = entityNestedOrderByDescending.Body.ToODataQuery(string.Empty); - visitor.Visit(entityNestedOrderByDescending.Body); - - _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{visitor.Query} {Constants.QuerySortDesc}{Constants.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{query} {Constants.QuerySortDesc}{Constants.QueryStringNestedSeparator}"); return this; } public IODataQueryNestedParameter Select(Expression> entityNestedSelect) { - var visitor = new SelectODataExpressionVisitor(); - - visitor.Visit(entityNestedSelect.Body); + var query = entityNestedSelect.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{query}{Constants.QueryStringNestedSeparator}"); return this; } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs index 42e53236..38a0db58 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs @@ -1,5 +1,5 @@ using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.ExpressionVisitors; +using OData.QueryBuilder.Extensions; using System; using System.Collections.Generic; using System.Linq.Expressions; @@ -16,11 +16,9 @@ public ODataQueryParameterKey(StringBuilder queryBuilder) => public IODataQueryParameterKey Expand(Expression> entityExpand) { - var visitor = new ExpandODataExpressionVisitor(); + var query = entityExpand.Body.ToODataQuery(string.Empty); - visitor.Visit(entityExpand.Body); - - _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{query}{Constants.QueryStringSeparator}"); return this; } @@ -38,11 +36,9 @@ public IODataQueryParameterKey Expand(Action Select(Expression> entitySelect) { - var visitor = new SelectODataExpressionVisitor(); - - visitor.Visit(entitySelect.Body); + var query = entitySelect.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{query}{Constants.QueryStringSeparator}"); return this; } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs index 8023d26f..1e009957 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs @@ -1,5 +1,5 @@ using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.ExpressionVisitors; +using OData.QueryBuilder.Extensions; using System; using System.Collections.Generic; using System.Linq.Expressions; @@ -16,22 +16,18 @@ public ODataQueryParameterList(StringBuilder queryBuilder) => public IODataQueryParameterList Filter(Expression> entityFilter) { - var visitor = new FilterODataExpressionVisitor(); + var query = entityFilter.Body.ToODataQuery(string.Empty); - visitor.Visit(entityFilter.Body); - - _queryBuilder.Append($"{Constants.QueryParameterFilter}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterFilter}{Constants.QueryStringEqualSign}{query}{Constants.QueryStringSeparator}"); return this; } public IODataQueryParameterList Expand(Expression> entityExpand) { - var visitor = new ExpandODataExpressionVisitor(); - - visitor.Visit(entityExpand.Body); + var query = entityExpand.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{query}{Constants.QueryStringSeparator}"); return this; } @@ -49,33 +45,27 @@ public IODataQueryParameterList Expand(Action Select(Expression> entitySelect) { - var visitor = new SelectODataExpressionVisitor(); - - visitor.Visit(entitySelect.Body); + var query = entitySelect.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{visitor.Query}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{query}{Constants.QueryStringSeparator}"); return this; } public IODataQueryParameterList OrderBy(Expression> entityOrderBy) { - var visitor = new OrderByODataExpressionVisitor(); + var query = entityOrderBy.Body.ToODataQuery(string.Empty); - visitor.Visit(entityOrderBy.Body); - - _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{visitor.Query} {Constants.QuerySortAsc}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{query} {Constants.QuerySortAsc}{Constants.QueryStringSeparator}"); return this; } public IODataQueryParameterList OrderByDescending(Expression> entityOrderByDescending) { - var visitor = new OrderByODataExpressionVisitor(); - - visitor.Visit(entityOrderByDescending.Body); + var query = entityOrderByDescending.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{visitor.Query} {Constants.QuerySortDesc}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{Constants.QueryParameterOrderBy}{Constants.QueryStringEqualSign}{query} {Constants.QuerySortDesc}{Constants.QueryStringSeparator}"); return this; } From e6724a04fa4d30eb49d1aa91301957e4426fde3b Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sat, 9 May 2020 16:09:48 +0300 Subject: [PATCH 07/76] #ZEX#fix test --- .../Extensions/ExpressionExtension.cs | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs b/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs index fb3edfab..61260cb3 100644 --- a/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs +++ b/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs @@ -7,30 +7,30 @@ namespace OData.QueryBuilder.Extensions { internal static class ExpressionExtension { - public static string GetODataLogicalOperator(this Expression expression) + public static string GetODataLogicalOperator(this ExpressionType expressionType) { - switch (expression.NodeType) + switch (expressionType) { case ExpressionType.And: case ExpressionType.AndAlso: - return $"and"; + return "and"; case ExpressionType.Or: case ExpressionType.OrElse: - return $"or"; + return "or"; case ExpressionType.Equal: - return $"eq"; + return "eq"; case ExpressionType.Not: - return $"not"; + return "not"; case ExpressionType.NotEqual: - return $"ne"; + return "ne"; case ExpressionType.LessThan: - return $"lt"; + return "lt"; case ExpressionType.LessThanOrEqual: - return $"le"; + return "le"; case ExpressionType.GreaterThan: - return $"gt"; + return "gt"; case ExpressionType.GreaterThanOrEqual: - return $"ge"; + return "ge"; default: return string.Empty; } @@ -150,16 +150,16 @@ public static string ToODataQueryFunctionDate(this BinaryExpression binaryExpres .Invoke(rightNewExpression.Arguments.Select(s => ((ConstantExpression)s).Value).ToArray())) .ToString("yyyy-MM-dd"); - return $"date({leftQuery}) {binaryExpression.GetODataLogicalOperator()} {rightQueryNew}"; + return $"date({leftQuery}) {binaryExpression.NodeType.GetODataLogicalOperator()} {rightQueryNew}"; case MemberExpression rightMemberExpression: var rightQueryMember = ((DateTime)rightMemberExpression.GetMemberExpressionValue()) .ToString("yyyy-MM-dd"); - return $"date({leftQuery}) {binaryExpression.GetODataLogicalOperator()} {rightQueryMember}"; + return $"date({leftQuery}) {binaryExpression.NodeType.GetODataLogicalOperator()} {rightQueryMember}"; case ConstantExpression rightConstantExpression: var rightQueryConstant = rightConstantExpression.ToODataQuery(); - return $"date({leftQuery}) {binaryExpression.GetODataLogicalOperator()} {rightQueryConstant}"; + return $"date({leftQuery}) {binaryExpression.NodeType.GetODataLogicalOperator()} {rightQueryConstant}"; } } else @@ -175,16 +175,16 @@ public static string ToODataQueryFunctionDate(this BinaryExpression binaryExpres var rightQueryUnary = ((DateTime)memberExpression.GetMemberExpressionValue()) .ToString("O"); - return $"{leftQuery} {binaryExpression.GetODataLogicalOperator()} {rightQueryUnary}"; + return $"{leftQuery} {binaryExpression.NodeType.GetODataLogicalOperator()} {rightQueryUnary}"; case MemberExpression rightMemberExpression: var rightQueryMember = ((DateTime)rightMemberExpression.GetMemberExpressionValue()) .ToString("O"); - return $"{leftQuery} {binaryExpression.GetODataLogicalOperator()} {rightQueryMember}"; + return $"{leftQuery} {binaryExpression.NodeType.GetODataLogicalOperator()} {rightQueryMember}"; case ConstantExpression rightConstantExpression: var rightQueryConstant = rightConstantExpression.ToODataQuery(); - return $"{leftQuery} {binaryExpression.GetODataLogicalOperator()} {rightQueryConstant}"; + return $"{leftQuery} {binaryExpression.NodeType.GetODataLogicalOperator()} {rightQueryConstant}"; } } } @@ -217,7 +217,7 @@ public static string ToODataQuery(this Expression expression, string queryString return leftQueryString; } - return $"{leftQueryString} {binaryExpression.GetODataLogicalOperator()} {rightQueryString}"; + return $"{leftQueryString} {binaryExpression.NodeType.GetODataLogicalOperator()} {rightQueryString}"; case MemberExpression memberExpression: var memberExpressionValue = memberExpression.GetMemberExpressionValue(); @@ -314,7 +314,8 @@ public static string ToODataQuery(this Expression expression, string queryString return newExpression.ToODataQuery(); case UnaryExpression unaryExpression: - var odataOperator = unaryExpression.GetODataLogicalOperator(); + var odataOperator = unaryExpression.NodeType.GetODataLogicalOperator(); + odataOperator = !string.IsNullOrEmpty(odataOperator) ? $"{odataOperator} " : string.Empty; return $"{odataOperator}{unaryExpression.Operand.ToODataQuery(queryString)}"; From ef2c04d61235a7795cac78708916cabc48ad8923 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sat, 9 May 2020 16:59:17 +0300 Subject: [PATCH 08/76] #ZEXSM#review --- .../Extensions/ExpressionExtension.cs | 16 ++++----- .../Parameters/IODataQueryParameterKey.cs | 2 +- .../Parameters/IODataQueryParameterList.cs | 2 +- .../Parameters/ODataQueryParameter.cs | 33 +++++++++++++++++++ .../Parameters/ODataQueryParameterKey.cs | 30 +++-------------- .../Parameters/ODataQueryParameterList.cs | 30 +++-------------- 6 files changed, 53 insertions(+), 60 deletions(-) create mode 100644 src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs diff --git a/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs b/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs index 61260cb3..fe47ad8f 100644 --- a/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs +++ b/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs @@ -92,14 +92,14 @@ public static string ToODataQuery(this ConstantExpression constantExpression) { switch (constantExpression.Value) { - case bool boolVal: - return boolVal.ToString().ToLower(); - case string stringVal: - return $"'{stringVal}'"; - case int intVal: - return intVal.ToString(); - case object objectVal: - return $"'{objectVal.ToString()}'"; + case bool b: + return b.ToString().ToLower(); + case int i: + return i.ToString(); + case string s: + return $"'{s}'"; + case object o: + return $"'{o}'"; default: return "null"; } diff --git a/src/OData.QueryBuilder/Parameters/IODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/IODataQueryParameterKey.cs index c44866f1..1b8fdc5d 100644 --- a/src/OData.QueryBuilder/Parameters/IODataQueryParameterKey.cs +++ b/src/OData.QueryBuilder/Parameters/IODataQueryParameterKey.cs @@ -4,7 +4,7 @@ namespace OData.QueryBuilder.Parameters { - public interface IODataQueryParameterKey : IODataQueryParameter + public interface IODataQueryParameterKey: IODataQueryParameter { IODataQueryParameterKey Expand(Expression> entityExpand); diff --git a/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs index 35dbd041..22cd723a 100644 --- a/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs @@ -4,7 +4,7 @@ namespace OData.QueryBuilder.Parameters { - public interface IODataQueryParameterList : IODataQueryParameter + public interface IODataQueryParameterList: IODataQueryParameter { IODataQueryParameterList Filter(Expression> entityFilter); diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs new file mode 100644 index 00000000..0c390f0a --- /dev/null +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OData.QueryBuilder.Parameters +{ + public class ODataQueryParameter : IODataQueryParameter + { + protected readonly StringBuilder _queryBuilder; + + public ODataQueryParameter(StringBuilder queryBuilder) => + _queryBuilder = queryBuilder; + + public Dictionary ToDictionary() + { + var odataOperators = _queryBuilder.ToString() + .Split(new char[2] { Constants.QueryCharBegin, Constants.QueryCharSeparator }, StringSplitOptions.RemoveEmptyEntries); + + var dictionary = new Dictionary(odataOperators.Length - 1); + + for (var step = 1; step < odataOperators.Length; step++) + { + var odataOperator = odataOperators[step].Split(Constants.QueryCharEqualSign); + + dictionary.Add(odataOperator[0], odataOperator[1]); + } + + return dictionary; + } + + public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd(Constants.QueryCharSeparator)); + } +} diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs index 38a0db58..a975cba2 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs @@ -1,18 +1,17 @@ using OData.QueryBuilder.Builders.Nested; using OData.QueryBuilder.Extensions; using System; -using System.Collections.Generic; using System.Linq.Expressions; using System.Text; namespace OData.QueryBuilder.Parameters { - public class ODataQueryParameterKey : IODataQueryParameterKey + public class ODataQueryParameterKey : ODataQueryParameter, IODataQueryParameterKey { - private readonly StringBuilder _queryBuilder; - - public ODataQueryParameterKey(StringBuilder queryBuilder) => - _queryBuilder = queryBuilder; + public ODataQueryParameterKey(StringBuilder queryBuilder) + : base(queryBuilder) + { + } public IODataQueryParameterKey Expand(Expression> entityExpand) { @@ -42,24 +41,5 @@ public IODataQueryParameterKey Select(Expression> return this; } - - public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd(Constants.QueryCharSeparator)); - - public Dictionary ToDictionary() - { - var odataOperators = _queryBuilder.ToString() - .Split(new char[2] { Constants.QueryCharBegin, Constants.QueryCharSeparator }, StringSplitOptions.RemoveEmptyEntries); - - var dictionary = new Dictionary(odataOperators.Length - 1); - - for (var step = 1; step < odataOperators.Length; step++) - { - var odataOperator = odataOperators[step].Split(Constants.QueryCharEqualSign); - - dictionary.Add(odataOperator[0], odataOperator[1]); - } - - return dictionary; - } } } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs index 1e009957..464f492d 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs @@ -1,18 +1,17 @@ using OData.QueryBuilder.Builders.Nested; using OData.QueryBuilder.Extensions; using System; -using System.Collections.Generic; using System.Linq.Expressions; using System.Text; namespace OData.QueryBuilder.Parameters { - public class ODataQueryParameterList : IODataQueryParameterList + public class ODataQueryParameterList : ODataQueryParameter, IODataQueryParameterList { - private readonly StringBuilder _queryBuilder; - - public ODataQueryParameterList(StringBuilder queryBuilder) => - _queryBuilder = queryBuilder; + public ODataQueryParameterList(StringBuilder queryBuilder) : + base(queryBuilder) + { + } public IODataQueryParameterList Filter(Expression> entityFilter) { @@ -90,24 +89,5 @@ public IODataQueryParameterList Count(bool value = true) return this; } - - public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd(Constants.QueryCharSeparator)); - - public Dictionary ToDictionary() - { - var odataOperators = _queryBuilder.ToString() - .Split(new char[2] { Constants.QueryCharBegin, Constants.QueryCharSeparator }, StringSplitOptions.RemoveEmptyEntries); - - var dictionary = new Dictionary(odataOperators.Length - 1); - - for (var step = 1; step < odataOperators.Length; step++) - { - var odataOperator = odataOperators[step].Split(Constants.QueryCharEqualSign); - - dictionary.Add(odataOperator[0], odataOperator[1]); - } - - return dictionary; - } } } From db93613f563f0867c201ecb51c74b021e78e9677 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sat, 9 May 2020 17:06:05 +0300 Subject: [PATCH 09/76] #ZEXSM#review --- .../Parameters/Nested/ODataQueryNestedParameter.cs | 3 ++- .../Parameters/Nested/ODataQueryNestedParameterBase.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs index 41dedc45..a6fa901e 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs @@ -2,13 +2,14 @@ using OData.QueryBuilder.Extensions; using System; using System.Linq.Expressions; +using System.Text; namespace OData.QueryBuilder.Parameters.Nested { public class ODataQueryNestedParameter : ODataQueryNestedParameterBase, IODataQueryNestedParameter { public ODataQueryNestedParameter() - : base() + : base(new StringBuilder()) { } diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs index 492f02ad..218e7b85 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs @@ -6,7 +6,8 @@ public abstract class ODataQueryNestedParameterBase { protected readonly StringBuilder _queryBuilder; - public ODataQueryNestedParameterBase() => _queryBuilder = new StringBuilder(); + public ODataQueryNestedParameterBase(StringBuilder queryBuilder) => + _queryBuilder = queryBuilder; public string Query => _queryBuilder.ToString().Trim(Constants.QueryCharNestedSeparator); } From ae0e3dce362edbc1535d20691cdeeff047dc16f8 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sat, 9 May 2020 19:26:15 +0300 Subject: [PATCH 10/76] #ZEXSM#review --- .../Builders/ODataQueryBuilder.cs | 8 +- .../Constants/ODataQueryFunctions.cs | 12 + .../Constants/ODataQueryParameters.cs | 13 + .../ODataQuerySeparators.cs} | 15 +- .../Constants/ODataQuerySorts.cs | 8 + .../Extensions/BinaryExpressionExtensions.cs | 99 ++++++ .../ConstantExpressionExtensions.cs | 24 ++ .../Extensions/ExpressionExtension.cs | 330 ------------------ .../Extensions/ExpressionExtensions.cs | 37 ++ .../Extensions/ExpressionTypeExtensions.cs | 36 ++ .../Extensions/LambdaExpressionExtensions.cs | 15 + .../Extensions/MemberExpressionExtensions.cs | 51 +++ ...onExtension.cs => MemberInfoExtensions.cs} | 2 +- .../MethodCallExpressionExtensions.cs | 116 ++++++ .../Extensions/NewExpressionExtensions.cs | 19 + .../Extensions/UnaryExpressionExtensions.cs | 15 + .../Nested/ODataQueryNestedParameter.cs | 15 +- .../Nested/ODataQueryNestedParameterBase.cs | 5 +- .../Parameters/ODataQueryParameter.cs | 9 +- .../Parameters/ODataQueryParameterKey.cs | 7 +- .../Parameters/ODataQueryParameterList.cs | 19 +- .../Resourses/ODataQueryResource.cs | 9 +- 22 files changed, 487 insertions(+), 377 deletions(-) create mode 100644 src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs create mode 100644 src/OData.QueryBuilder/Constants/ODataQueryParameters.cs rename src/OData.QueryBuilder/{Parameters/Constants.cs => Constants/ODataQuerySeparators.cs} (52%) create mode 100644 src/OData.QueryBuilder/Constants/ODataQuerySorts.cs create mode 100644 src/OData.QueryBuilder/Extensions/BinaryExpressionExtensions.cs create mode 100644 src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs delete mode 100644 src/OData.QueryBuilder/Extensions/ExpressionExtension.cs create mode 100644 src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs create mode 100644 src/OData.QueryBuilder/Extensions/ExpressionTypeExtensions.cs create mode 100644 src/OData.QueryBuilder/Extensions/LambdaExpressionExtensions.cs create mode 100644 src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs rename src/OData.QueryBuilder/Extensions/{ReflectionExtension.cs => MemberInfoExtensions.cs} (93%) create mode 100644 src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs create mode 100644 src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs create mode 100644 src/OData.QueryBuilder/Extensions/UnaryExpressionExtensions.cs diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index b9d5f87b..54da2ac9 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -1,5 +1,5 @@ -using OData.QueryBuilder.Extensions; -using OData.QueryBuilder.Parameters; +using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Extensions; using OData.QueryBuilder.Resourses; using System; using System.Linq.Expressions; @@ -11,10 +11,10 @@ public class ODataQueryBuilder : IODataQueryBuilder private readonly string _baseUrl; public ODataQueryBuilder(Uri baseUrl) => - _baseUrl = $"{baseUrl.OriginalString.TrimEnd(Constants.SlashCharSeparator)}{Constants.SlashStringSeparator}"; + _baseUrl = $"{baseUrl.OriginalString.TrimEnd(ODataQuerySeparators.SlashCharSeparator)}{ODataQuerySeparators.SlashStringSeparator}"; public ODataQueryBuilder(string baseUrl) => - _baseUrl = $"{baseUrl.TrimEnd(Constants.SlashCharSeparator)}{Constants.SlashStringSeparator}"; + _baseUrl = $"{baseUrl.TrimEnd(ODataQuerySeparators.SlashCharSeparator)}{ODataQuerySeparators.SlashStringSeparator}"; public IODataQueryResource For(Expression> entityResource) => new ODataQueryResource($"{_baseUrl}{entityResource.Body.ToODataQuery(string.Empty)}"); diff --git a/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs b/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs new file mode 100644 index 00000000..f4a79ed3 --- /dev/null +++ b/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs @@ -0,0 +1,12 @@ +namespace OData.QueryBuilder.Constants +{ + internal struct ODataQueryFunctions + { + public const string Any = "any"; + public const string All = "all"; + public const string Date = "date"; + public const string Substringof = "substringof"; + public const string Toupper = "toupper"; + public const string In = "in"; + } +} diff --git a/src/OData.QueryBuilder/Constants/ODataQueryParameters.cs b/src/OData.QueryBuilder/Constants/ODataQueryParameters.cs new file mode 100644 index 00000000..f9976f9b --- /dev/null +++ b/src/OData.QueryBuilder/Constants/ODataQueryParameters.cs @@ -0,0 +1,13 @@ +namespace OData.QueryBuilder.Constants +{ + internal struct ODataQueryParameters + { + public const string QueryParameterSelect = "$select"; + public const string QueryParameterExpand = "$expand"; + public const string QueryParameterFilter = "$filter"; + public const string QueryParameterOrderBy = "$orderby"; + public const string QueryParameterTop = "$top"; + public const string QueryParameterSkip = "$skip"; + public const string QueryParameterCount = "$count"; + } +} diff --git a/src/OData.QueryBuilder/Parameters/Constants.cs b/src/OData.QueryBuilder/Constants/ODataQuerySeparators.cs similarity index 52% rename from src/OData.QueryBuilder/Parameters/Constants.cs rename to src/OData.QueryBuilder/Constants/ODataQuerySeparators.cs index 68dc4563..59898db2 100644 --- a/src/OData.QueryBuilder/Parameters/Constants.cs +++ b/src/OData.QueryBuilder/Constants/ODataQuerySeparators.cs @@ -1,6 +1,6 @@ -namespace OData.QueryBuilder.Parameters +namespace OData.QueryBuilder.Constants { - internal struct Constants + internal struct ODataQuerySeparators { public const string QueryStringSeparator = "&"; public const char QueryCharSeparator = '&'; @@ -14,16 +14,5 @@ internal struct Constants public const char SlashCharSeparator = '/'; public const string CommaStringSeparator = ","; public const char DotCharSeparator = '.'; - - public const string QueryParameterSelect = "$select"; - public const string QueryParameterExpand = "$expand"; - public const string QueryParameterFilter = "$filter"; - public const string QueryParameterOrderBy = "$orderby"; - public const string QueryParameterTop = "$top"; - public const string QueryParameterSkip = "$skip"; - public const string QueryParameterCount = "$count"; - - public const string QuerySortAsc = "asc"; - public const string QuerySortDesc = "desc"; } } diff --git a/src/OData.QueryBuilder/Constants/ODataQuerySorts.cs b/src/OData.QueryBuilder/Constants/ODataQuerySorts.cs new file mode 100644 index 00000000..d46ca8b6 --- /dev/null +++ b/src/OData.QueryBuilder/Constants/ODataQuerySorts.cs @@ -0,0 +1,8 @@ +namespace OData.QueryBuilder.Constants +{ + internal struct ODataQuerySorts + { + public const string QuerySortAsc = "asc"; + public const string QuerySortDesc = "desc"; + } +} diff --git a/src/OData.QueryBuilder/Extensions/BinaryExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/BinaryExpressionExtensions.cs new file mode 100644 index 00000000..4fdb8c16 --- /dev/null +++ b/src/OData.QueryBuilder/Extensions/BinaryExpressionExtensions.cs @@ -0,0 +1,99 @@ +using OData.QueryBuilder.Constants; +using System; +using System.Linq; +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Extensions +{ + internal static class BinaryExpressionExtensions + { + public static string ToODataQuery(this BinaryExpression binaryExpression, string queryString) + { + var funcDateQuery = binaryExpression.ToODataQueryFunctionDate(); + if (!string.IsNullOrEmpty(funcDateQuery)) + { + return funcDateQuery; + } + + var leftQueryString = binaryExpression.Left.ToODataQuery(queryString); + var rightQueryString = binaryExpression.Right.ToODataQuery(queryString); + + if (string.IsNullOrEmpty(leftQueryString)) + { + return rightQueryString; + } + + if (string.IsNullOrEmpty(rightQueryString)) + { + return leftQueryString; + } + + return $"{leftQueryString} {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryString}"; + } + + public static string ToODataQueryFunctionDate(this BinaryExpression binaryExpression) + { + if (binaryExpression.Left.Type == typeof(DateTime) || binaryExpression.Left.Type == typeof(DateTimeOffset) + || binaryExpression.Left.Type == typeof(DateTime?) || binaryExpression.Left.Type == typeof(DateTimeOffset?)) + { + var leftExpression = binaryExpression.Left as MemberExpression ?? + (binaryExpression.Left as UnaryExpression).Operand as MemberExpression ?? + ((binaryExpression.Left as UnaryExpression).Operand as UnaryExpression).Operand as MemberExpression; + + if (leftExpression != default(MemberExpression)) + { + if (leftExpression.Member.Name == nameof(DateTime.Date)) + { + var leftQuery = leftExpression.Expression.ToODataQuery(string.Empty); + + switch (binaryExpression.Right) + { + case NewExpression rightNewExpression: + var rightQueryNew = ((DateTime)rightNewExpression.Constructor + .Invoke(rightNewExpression.Arguments.Select(s => ((ConstantExpression)s).Value).ToArray())) + .ToString("yyyy-MM-dd"); + + return $"{ODataQueryFunctions.Date}({leftQuery}) {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryNew}"; + case MemberExpression rightMemberExpression: + var rightQueryMember = ((DateTime)rightMemberExpression.GetMemberValue()) + .ToString("yyyy-MM-dd"); + + return $"{ODataQueryFunctions.Date}({leftQuery}) {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryMember}"; + case ConstantExpression rightConstantExpression: + var rightQueryConstant = rightConstantExpression.ToODataQuery(); + + return $"{ODataQueryFunctions.Date}({leftQuery}) {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryConstant}"; + } + } + else + { + var leftQuery = leftExpression.ToODataQuery(string.Empty); + + switch (binaryExpression.Right) + { + case UnaryExpression rightUnaryExpression: + var memberExpression = rightUnaryExpression.Operand as MemberExpression ?? + (rightUnaryExpression.Operand as UnaryExpression).Operand as MemberExpression; + + var rightQueryUnary = ((DateTime)memberExpression.GetMemberValue()) + .ToString("O"); + + return $"{leftQuery} {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryUnary}"; + case MemberExpression rightMemberExpression: + var rightQueryMember = ((DateTime)rightMemberExpression.GetMemberValue()) + .ToString("O"); + + return $"{leftQuery} {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryMember}"; + case ConstantExpression rightConstantExpression: + var rightQueryConstant = rightConstantExpression.ToODataQuery(); + + return $"{leftQuery} {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryConstant}"; + } + } + } + } + + return string.Empty; + } + } +} diff --git a/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs new file mode 100644 index 00000000..f7a3ffeb --- /dev/null +++ b/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs @@ -0,0 +1,24 @@ +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Extensions +{ + internal static class ConstantExpressionExtensions + { + public static string ToODataQuery(this ConstantExpression constantExpression) + { + switch (constantExpression.Value) + { + case bool b: + return b.ToString().ToLower(); + case int i: + return i.ToString(); + case string s: + return $"'{s}'"; + case object o: + return $"'{o}'"; + default: + return "null"; + } + } + } +} diff --git a/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs b/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs deleted file mode 100644 index fe47ad8f..00000000 --- a/src/OData.QueryBuilder/Extensions/ExpressionExtension.cs +++ /dev/null @@ -1,330 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Extensions -{ - internal static class ExpressionExtension - { - public static string GetODataLogicalOperator(this ExpressionType expressionType) - { - switch (expressionType) - { - case ExpressionType.And: - case ExpressionType.AndAlso: - return "and"; - case ExpressionType.Or: - case ExpressionType.OrElse: - return "or"; - case ExpressionType.Equal: - return "eq"; - case ExpressionType.Not: - return "not"; - case ExpressionType.NotEqual: - return "ne"; - case ExpressionType.LessThan: - return "lt"; - case ExpressionType.LessThanOrEqual: - return "le"; - case ExpressionType.GreaterThan: - return "gt"; - case ExpressionType.GreaterThanOrEqual: - return "ge"; - default: - return string.Empty; - } - } - - public static object GetMemberExpressionValue(this MemberExpression memberExpression) - { - if (memberExpression.Expression is ConstantExpression) - { - var constantValue = (memberExpression.Expression as ConstantExpression).Value; - return memberExpression.Member.GetValue(constantValue); - } - - if (memberExpression.Expression is MemberExpression) - { - var memberValue = GetMemberExpressionValue(memberExpression.Expression as MemberExpression); - return memberExpression.Member.GetValue(memberValue); - } - - return memberExpression.Member.GetValue(default(object)); - } - - public static string GetInSequence(this object arrayObj) - { - if (arrayObj == default(object)) - { - return default(string); - } - if (arrayObj is IEnumerable) - { - var inSequenceInt = string.Join(",", arrayObj as IEnumerable); - if (!string.IsNullOrEmpty(inSequenceInt)) - { - return $"in ({inSequenceInt})"; - } - else - { - return default(string); - } - } - - if (arrayObj is IEnumerable) - { - var inSequenceInt = string.Join("','", arrayObj as IEnumerable); - if (!string.IsNullOrEmpty(inSequenceInt)) - { - return $"in ('{inSequenceInt}')"; - } - else - { - return default(string); - } - } - - return string.Empty; - } - - public static string ToODataQuery(this ConstantExpression constantExpression) - { - switch (constantExpression.Value) - { - case bool b: - return b.ToString().ToLower(); - case int i: - return i.ToString(); - case string s: - return $"'{s}'"; - case object o: - return $"'{o}'"; - default: - return "null"; - } - } - - public static string ToODataQuery(this MemberExpression memberExpression) => - memberExpression.Member.Name; - - public static string ToODataQuery(this LambdaExpression lambdaExpression) - { - var filter = lambdaExpression.Body.ToODataQuery(string.Empty); - var tag = lambdaExpression.Parameters[0]?.Name; - - return $"{tag}:{tag}/{filter}"; - } - - public static string ToODataQuery(this NewExpression newExpression) - { - var names = new string[newExpression.Members.Count]; - - for (var i = 0; i < newExpression.Members.Count; i++) - { - names[i] = newExpression.Members[i].Name; - } - - return string.Join(",", names); - } - - public static string ToODataQueryFunctionDate(this BinaryExpression binaryExpression) - { - if (binaryExpression.Left.Type == typeof(DateTime) || binaryExpression.Left.Type == typeof(DateTimeOffset) - || binaryExpression.Left.Type == typeof(DateTime?) || binaryExpression.Left.Type == typeof(DateTimeOffset?)) - { - var leftExpression = binaryExpression.Left as MemberExpression ?? - (binaryExpression.Left as UnaryExpression).Operand as MemberExpression ?? - ((binaryExpression.Left as UnaryExpression).Operand as UnaryExpression).Operand as MemberExpression; - - if (leftExpression != default(MemberExpression)) - { - if (leftExpression.ToODataQuery() == nameof(DateTime.Date)) - { - var leftQuery = leftExpression.Expression.ToODataQuery(string.Empty); - - switch (binaryExpression.Right) - { - case NewExpression rightNewExpression: - var rightQueryNew = ((DateTime)rightNewExpression.Constructor - .Invoke(rightNewExpression.Arguments.Select(s => ((ConstantExpression)s).Value).ToArray())) - .ToString("yyyy-MM-dd"); - - return $"date({leftQuery}) {binaryExpression.NodeType.GetODataLogicalOperator()} {rightQueryNew}"; - case MemberExpression rightMemberExpression: - var rightQueryMember = ((DateTime)rightMemberExpression.GetMemberExpressionValue()) - .ToString("yyyy-MM-dd"); - - return $"date({leftQuery}) {binaryExpression.NodeType.GetODataLogicalOperator()} {rightQueryMember}"; - case ConstantExpression rightConstantExpression: - var rightQueryConstant = rightConstantExpression.ToODataQuery(); - - return $"date({leftQuery}) {binaryExpression.NodeType.GetODataLogicalOperator()} {rightQueryConstant}"; - } - } - else - { - var leftQuery = leftExpression.ToODataQuery(string.Empty); - - switch (binaryExpression.Right) - { - case UnaryExpression rightUnaryExpression: - var memberExpression = rightUnaryExpression.Operand as MemberExpression ?? - (rightUnaryExpression.Operand as UnaryExpression).Operand as MemberExpression; - - var rightQueryUnary = ((DateTime)memberExpression.GetMemberExpressionValue()) - .ToString("O"); - - return $"{leftQuery} {binaryExpression.NodeType.GetODataLogicalOperator()} {rightQueryUnary}"; - case MemberExpression rightMemberExpression: - var rightQueryMember = ((DateTime)rightMemberExpression.GetMemberExpressionValue()) - .ToString("O"); - - return $"{leftQuery} {binaryExpression.NodeType.GetODataLogicalOperator()} {rightQueryMember}"; - case ConstantExpression rightConstantExpression: - var rightQueryConstant = rightConstantExpression.ToODataQuery(); - - return $"{leftQuery} {binaryExpression.NodeType.GetODataLogicalOperator()} {rightQueryConstant}"; - } - } - } - } - - return string.Empty; - } - - public static string ToODataQuery(this Expression expression, string queryString) - { - switch (expression) - { - case BinaryExpression binaryExpression: - var funcDateQuery = binaryExpression.ToODataQueryFunctionDate(); - if (!string.IsNullOrEmpty(funcDateQuery)) - { - return funcDateQuery; - } - - var leftQueryString = binaryExpression.Left.ToODataQuery(queryString); - var rightQueryString = binaryExpression.Right.ToODataQuery(queryString); - - if (string.IsNullOrEmpty(leftQueryString)) - { - return rightQueryString; - } - - if (string.IsNullOrEmpty(rightQueryString)) - { - return leftQueryString; - } - - return $"{leftQueryString} {binaryExpression.NodeType.GetODataLogicalOperator()} {rightQueryString}"; - - case MemberExpression memberExpression: - var memberExpressionValue = memberExpression.GetMemberExpressionValue(); - - if (memberExpressionValue != default(object)) - { - if (memberExpressionValue is string) - { - return $"'{memberExpressionValue}'"; - } - - if (memberExpressionValue is bool) - { - return $"{memberExpressionValue}".ToLower(); - } - - return $"{memberExpressionValue}"; - } - - var parentMemberExpressionQuery = memberExpression.Expression.ToODataQuery(queryString); - - if (string.IsNullOrEmpty(parentMemberExpressionQuery)) - { - return memberExpression.ToODataQuery(); - } - - return $"{parentMemberExpressionQuery}/{memberExpression.ToODataQuery()}"; - - case ConstantExpression constantExpression: - return constantExpression.ToODataQuery(); - - case MethodCallExpression methodCallExpression: - var methodName = methodCallExpression.Method.Name; - - if (methodName == nameof(Enumerable.Any) || methodName == nameof(Enumerable.All)) - { - var resource = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); - var filter = methodCallExpression.Arguments[1]?.ToODataQuery(queryString); - - return $"{resource}/{methodName.ToLower()}({filter})"; - } - - if (methodName == nameof(Enumerable.Contains)) - { - var resource = default(object); - var filter = default(string); - - if (methodCallExpression.Object == default(Expression)) - { - resource = (methodCallExpression.Arguments[0] as MemberExpression).GetMemberExpressionValue(); - filter = methodCallExpression.Arguments[1].ToODataQuery(queryString); - } - else if (methodCallExpression.Object is MemberExpression) - { - resource = (methodCallExpression.Object as MemberExpression).GetMemberExpressionValue() ?? - methodCallExpression.Object.ToODataQuery(string.Empty); - - filter = methodCallExpression.Arguments[0].ToODataQuery(queryString); - } - else if (methodCallExpression.Object is MethodCallExpression) - { - resource = methodCallExpression.Object.ToODataQuery(string.Empty); - filter = methodCallExpression.Arguments[0].ToODataQuery(string.Empty); - } - - var inSequence = resource.GetInSequence(); - - if (inSequence != default(string)) - { - if (!string.IsNullOrEmpty(inSequence)) - { - return $"{filter} {inSequence}"; - } - else - { - return $"substringof({filter},{resource})"; - } - } - } - - if (methodName == nameof(string.ToUpper)) - { - return $"toupper({methodCallExpression.Object.ToODataQuery(string.Empty)})"; - } - - if (methodName == nameof(ToString)) - { - return methodCallExpression.Object.ToODataQuery(string.Empty); - } - - return string.Empty; - - case NewExpression newExpression: - return newExpression.ToODataQuery(); - - case UnaryExpression unaryExpression: - var odataOperator = unaryExpression.NodeType.GetODataLogicalOperator(); - odataOperator = !string.IsNullOrEmpty(odataOperator) ? $"{odataOperator} " : string.Empty; - - return $"{odataOperator}{unaryExpression.Operand.ToODataQuery(queryString)}"; - - case LambdaExpression lambdaExpression: - return lambdaExpression.ToODataQuery(); - - default: - return string.Empty; - } - } - } -} diff --git a/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs new file mode 100644 index 00000000..d0ae9ab2 --- /dev/null +++ b/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs @@ -0,0 +1,37 @@ +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Extensions +{ + internal static class ExpressionExtensions + { + public static string ToODataQuery(this Expression expression, string queryString) + { + switch (expression) + { + case BinaryExpression binaryExpression: + return binaryExpression.ToODataQuery(queryString); + + case MemberExpression memberExpression: + return memberExpression.ToODataQuery(queryString); + + case ConstantExpression constantExpression: + return constantExpression.ToODataQuery(); + + case MethodCallExpression methodCallExpression: + return methodCallExpression.ToODataQuery(queryString); + + case NewExpression newExpression: + return newExpression.ToODataQuery(); + + case UnaryExpression unaryExpression: + return unaryExpression.ToODataQuery(queryString); + + case LambdaExpression lambdaExpression: + return lambdaExpression.ToODataQuery(); + + default: + return string.Empty; + } + } + } +} diff --git a/src/OData.QueryBuilder/Extensions/ExpressionTypeExtensions.cs b/src/OData.QueryBuilder/Extensions/ExpressionTypeExtensions.cs new file mode 100644 index 00000000..d22d3f85 --- /dev/null +++ b/src/OData.QueryBuilder/Extensions/ExpressionTypeExtensions.cs @@ -0,0 +1,36 @@ +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Extensions +{ + internal static class ExpressionTypeExtensions + { + public static string ToODataQueryOperator(this ExpressionType expressionType) + { + switch (expressionType) + { + case ExpressionType.And: + case ExpressionType.AndAlso: + return "and"; + case ExpressionType.Or: + case ExpressionType.OrElse: + return "or"; + case ExpressionType.Equal: + return "eq"; + case ExpressionType.Not: + return "not"; + case ExpressionType.NotEqual: + return "ne"; + case ExpressionType.LessThan: + return "lt"; + case ExpressionType.LessThanOrEqual: + return "le"; + case ExpressionType.GreaterThan: + return "gt"; + case ExpressionType.GreaterThanOrEqual: + return "ge"; + default: + return string.Empty; + } + } + } +} diff --git a/src/OData.QueryBuilder/Extensions/LambdaExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/LambdaExpressionExtensions.cs new file mode 100644 index 00000000..9721aaa4 --- /dev/null +++ b/src/OData.QueryBuilder/Extensions/LambdaExpressionExtensions.cs @@ -0,0 +1,15 @@ +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Extensions +{ + internal static class LambdaExpressionExtensions + { + public static string ToODataQuery(this LambdaExpression lambdaExpression) + { + var filter = lambdaExpression.Body.ToODataQuery(string.Empty); + var tag = lambdaExpression.Parameters[0]?.Name; + + return $"{tag}:{tag}/{filter}"; + } + } +} diff --git a/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs new file mode 100644 index 00000000..30924c70 --- /dev/null +++ b/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs @@ -0,0 +1,51 @@ +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Extensions +{ + internal static class MemberExpressionExtensions + { + public static object GetMemberValue(this MemberExpression memberExpression) + { + if (memberExpression.Expression is ConstantExpression ce) + { + return memberExpression.Member.GetValue(ce.Value); + } + + if (memberExpression.Expression is MemberExpression me) + { + return memberExpression.Member.GetValue(GetMemberValue(me)); + } + + return memberExpression.Member.GetValue(); + } + + public static string ToODataQuery(this MemberExpression memberExpression, string queryString) + { + var memberExpressionValue = memberExpression.GetMemberValue(); + + if (memberExpressionValue != default(object)) + { + if (memberExpressionValue is string) + { + return $"'{memberExpressionValue}'"; + } + + if (memberExpressionValue is bool) + { + return $"{memberExpressionValue}".ToLower(); + } + + return $"{memberExpressionValue}"; + } + + var parentMemberExpressionQuery = memberExpression.Expression.ToODataQuery(queryString); + + if (string.IsNullOrEmpty(parentMemberExpressionQuery)) + { + return memberExpression.Member.Name; + } + + return $"{parentMemberExpressionQuery}/{memberExpression.Member.Name}"; + } + } +} diff --git a/src/OData.QueryBuilder/Extensions/ReflectionExtension.cs b/src/OData.QueryBuilder/Extensions/MemberInfoExtensions.cs similarity index 93% rename from src/OData.QueryBuilder/Extensions/ReflectionExtension.cs rename to src/OData.QueryBuilder/Extensions/MemberInfoExtensions.cs index 232b65a1..9c67dbc0 100644 --- a/src/OData.QueryBuilder/Extensions/ReflectionExtension.cs +++ b/src/OData.QueryBuilder/Extensions/MemberInfoExtensions.cs @@ -3,7 +3,7 @@ namespace OData.QueryBuilder.Extensions { - internal static class ReflectionExtension + internal static class MemberInfoExtensions { public static object GetValue(this MemberInfo memberInfo, object obj = default) { diff --git a/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs new file mode 100644 index 00000000..3e188318 --- /dev/null +++ b/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs @@ -0,0 +1,116 @@ +using OData.QueryBuilder.Constants; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Extensions +{ + internal static class MethodCallExpressionExtensions + { + public static string ToODataQuery(this MethodCallExpression methodCallExpression, string queryString) + { + var methodName = methodCallExpression.Method.Name; + + if (methodName == nameof(Enumerable.All)) + { + var resource = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); + var filter = methodCallExpression.Arguments[1]?.ToODataQuery(queryString); + + return $"{resource}/{ODataQueryFunctions.All}({filter})"; + } + + if (methodName == nameof(Enumerable.Any)) + { + var resource = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); + var filter = methodCallExpression.Arguments[1]?.ToODataQuery(queryString); + + return $"{resource}/{ODataQueryFunctions.Any}({filter})"; + } + + if (methodName == nameof(Enumerable.Contains)) + { + var resource = default(object); + var filter = default(string); + + if (methodCallExpression.Object == default(Expression)) + { + resource = (methodCallExpression.Arguments[0] as MemberExpression).GetMemberValue(); + filter = methodCallExpression.Arguments[1].ToODataQuery(queryString); + } + else if (methodCallExpression.Object is MemberExpression) + { + resource = (methodCallExpression.Object as MemberExpression).GetMemberValue() ?? + methodCallExpression.Object.ToODataQuery(string.Empty); + + filter = methodCallExpression.Arguments[0].ToODataQuery(queryString); + } + else if (methodCallExpression.Object is MethodCallExpression) + { + resource = methodCallExpression.Object.ToODataQuery(string.Empty); + filter = methodCallExpression.Arguments[0].ToODataQuery(string.Empty); + } + + var inSequence = resource.GetInSequence(); + + if (inSequence != default) + { + if (!string.IsNullOrEmpty(inSequence)) + { + return $"{filter} {inSequence}"; + } + else + { + return $"{ODataQueryFunctions.Substringof}({filter},{resource})"; + } + } + } + + if (methodName == nameof(string.ToUpper)) + { + return $"{ODataQueryFunctions.Toupper}({methodCallExpression.Object.ToODataQuery(string.Empty)})"; + } + + if (methodName == nameof(ToString)) + { + return methodCallExpression.Object.ToODataQuery(string.Empty); + } + + return string.Empty; + } + + private static string GetInSequence(this object arrayObj) + { + if (arrayObj == default) + { + return default; + } + if (arrayObj is IEnumerable) + { + var inSequenceInt = string.Join(",", arrayObj as IEnumerable); + if (!string.IsNullOrEmpty(inSequenceInt)) + { + return $"{ODataQueryFunctions.In} ({inSequenceInt})"; + } + else + { + return default; + } + } + + if (arrayObj is IEnumerable) + { + var inSequenceInt = string.Join("','", arrayObj as IEnumerable); + if (!string.IsNullOrEmpty(inSequenceInt)) + { + return $"{ODataQueryFunctions.In} ('{inSequenceInt}')"; + } + else + { + return default; + } + } + + return string.Empty; + } + } +} diff --git a/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs new file mode 100644 index 00000000..5bc793be --- /dev/null +++ b/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs @@ -0,0 +1,19 @@ +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Extensions +{ + internal static class NewExpressionExtensions + { + public static string ToODataQuery(this NewExpression newExpression) + { + var names = new string[newExpression.Members.Count]; + + for (var i = 0; i < newExpression.Members.Count; i++) + { + names[i] = newExpression.Members[i].Name; + } + + return string.Join(",", names); + } + } +} diff --git a/src/OData.QueryBuilder/Extensions/UnaryExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/UnaryExpressionExtensions.cs new file mode 100644 index 00000000..9b404cb3 --- /dev/null +++ b/src/OData.QueryBuilder/Extensions/UnaryExpressionExtensions.cs @@ -0,0 +1,15 @@ +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Extensions +{ + internal static class UnaryExpressionExtensions + { + public static string ToODataQuery(this UnaryExpression unaryExpression, string queryString) + { + var odataOperator = unaryExpression.NodeType.ToODataQueryOperator(); + odataOperator = !string.IsNullOrEmpty(odataOperator) ? $"{odataOperator} " : string.Empty; + + return $"{odataOperator}{unaryExpression.Operand.ToODataQuery(queryString)}"; + } + } +} diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs index a6fa901e..72940497 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs @@ -1,4 +1,5 @@ using OData.QueryBuilder.Builders.Nested; +using OData.QueryBuilder.Constants; using OData.QueryBuilder.Extensions; using System; using System.Linq.Expressions; @@ -17,7 +18,7 @@ public IODataQueryNestedParameter Expand(Expression Expand(Action Filter(Expression { var query = entityNestedFilter.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{Constants.QueryParameterFilter}{Constants.QueryStringEqualSign}{query}{Constants.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.QueryParameterFilter}{ODataQuerySeparators.QueryStringEqualSign}{query}{ODataQuerySeparators.QueryStringNestedSeparator}"); return this; } @@ -46,7 +47,7 @@ public IODataQueryNestedParameter OrderBy(Expression OrderByDescending(Expression Select(Expression Top(int value) { - _queryBuilder.Append($"{Constants.QueryParameterTop}{Constants.QueryStringEqualSign}{value}{Constants.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.QueryParameterTop}{ODataQuerySeparators.QueryStringEqualSign}{value}{ODataQuerySeparators.QueryStringNestedSeparator}"); return this; } diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs index 218e7b85..ac56d3b9 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs @@ -1,4 +1,5 @@ -using System.Text; +using OData.QueryBuilder.Constants; +using System.Text; namespace OData.QueryBuilder.Parameters.Nested { @@ -9,6 +10,6 @@ public abstract class ODataQueryNestedParameterBase public ODataQueryNestedParameterBase(StringBuilder queryBuilder) => _queryBuilder = queryBuilder; - public string Query => _queryBuilder.ToString().Trim(Constants.QueryCharNestedSeparator); + public string Query => _queryBuilder.ToString().Trim(ODataQuerySeparators.QueryCharNestedSeparator); } } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs index 0c390f0a..5170a315 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs @@ -1,4 +1,5 @@ -using System; +using OData.QueryBuilder.Constants; +using System; using System.Collections.Generic; using System.Text; @@ -14,13 +15,13 @@ public ODataQueryParameter(StringBuilder queryBuilder) => public Dictionary ToDictionary() { var odataOperators = _queryBuilder.ToString() - .Split(new char[2] { Constants.QueryCharBegin, Constants.QueryCharSeparator }, StringSplitOptions.RemoveEmptyEntries); + .Split(new char[2] { ODataQuerySeparators.QueryCharBegin, ODataQuerySeparators.QueryCharSeparator }, StringSplitOptions.RemoveEmptyEntries); var dictionary = new Dictionary(odataOperators.Length - 1); for (var step = 1; step < odataOperators.Length; step++) { - var odataOperator = odataOperators[step].Split(Constants.QueryCharEqualSign); + var odataOperator = odataOperators[step].Split(ODataQuerySeparators.QueryCharEqualSign); dictionary.Add(odataOperator[0], odataOperator[1]); } @@ -28,6 +29,6 @@ public Dictionary ToDictionary() return dictionary; } - public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd(Constants.QueryCharSeparator)); + public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd(ODataQuerySeparators.QueryCharSeparator)); } } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs index a975cba2..148b3528 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs @@ -1,4 +1,5 @@ using OData.QueryBuilder.Builders.Nested; +using OData.QueryBuilder.Constants; using OData.QueryBuilder.Extensions; using System; using System.Linq.Expressions; @@ -17,7 +18,7 @@ public IODataQueryParameterKey Expand(Expression> { var query = entityExpand.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{query}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.QueryParameterExpand}{ODataQuerySeparators.QueryStringEqualSign}{query}{ODataQuerySeparators.QueryStringSeparator}"); return this; } @@ -28,7 +29,7 @@ public IODataQueryParameterKey Expand(Action Select(Expression> { var query = entitySelect.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{query}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.QueryParameterSelect}{ODataQuerySeparators.QueryStringEqualSign}{query}{ODataQuerySeparators.QueryStringSeparator}"); return this; } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs index 464f492d..bf18bd5d 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs @@ -1,4 +1,5 @@ using OData.QueryBuilder.Builders.Nested; +using OData.QueryBuilder.Constants; using OData.QueryBuilder.Extensions; using System; using System.Linq.Expressions; @@ -17,7 +18,7 @@ public IODataQueryParameterList Filter(Expression> { var query = entityFilter.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{Constants.QueryParameterFilter}{Constants.QueryStringEqualSign}{query}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.QueryParameterFilter}{ODataQuerySeparators.QueryStringEqualSign}{query}{ODataQuerySeparators.QueryStringSeparator}"); return this; } @@ -26,7 +27,7 @@ public IODataQueryParameterList Expand(Expression { var query = entityExpand.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{Constants.QueryParameterExpand}{Constants.QueryStringEqualSign}{query}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.QueryParameterExpand}{ODataQuerySeparators.QueryStringEqualSign}{query}{ODataQuerySeparators.QueryStringSeparator}"); return this; } @@ -37,7 +38,7 @@ public IODataQueryParameterList Expand(Action Select(Expression { var query = entitySelect.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{Constants.QueryParameterSelect}{Constants.QueryStringEqualSign}{query}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.QueryParameterSelect}{ODataQuerySeparators.QueryStringEqualSign}{query}{ODataQuerySeparators.QueryStringSeparator}"); return this; } @@ -55,7 +56,7 @@ public IODataQueryParameterList OrderBy(Expression OrderByDescending(Expression Skip(int value) { - _queryBuilder.Append($"{Constants.QueryParameterSkip}{Constants.QueryStringEqualSign}{value}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.QueryParameterSkip}{ODataQuerySeparators.QueryStringEqualSign}{value}{ODataQuerySeparators.QueryStringSeparator}"); return this; } public IODataQueryParameterList Top(int value) { - _queryBuilder.Append($"{Constants.QueryParameterTop}{Constants.QueryStringEqualSign}{value}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.QueryParameterTop}{ODataQuerySeparators.QueryStringEqualSign}{value}{ODataQuerySeparators.QueryStringSeparator}"); return this; } public IODataQueryParameterList Count(bool value = true) { - _queryBuilder.Append($"{Constants.QueryParameterCount}{Constants.QueryStringEqualSign}{value.ToString().ToLower()}{Constants.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.QueryParameterCount}{ODataQuerySeparators.QueryStringEqualSign}{value.ToString().ToLower()}{ODataQuerySeparators.QueryStringSeparator}"); return this; } diff --git a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs b/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs index 02b806c7..22731db1 100644 --- a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs +++ b/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs @@ -1,4 +1,5 @@ -using OData.QueryBuilder.Parameters; +using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Parameters; using System.Text; namespace OData.QueryBuilder.Resourses @@ -12,21 +13,21 @@ public ODataQueryResource(string resourceUrl) => public IODataQueryParameterKey ByKey(int key) { - _queryBuilder.Append($"({key}){Constants.QueryStringBegin}"); + _queryBuilder.Append($"({key}){ODataQuerySeparators.QueryStringBegin}"); return new ODataQueryParameterKey(_queryBuilder); } public IODataQueryParameterKey ByKey(string key) { - _queryBuilder.Append($"('{key}'){Constants.QueryStringBegin}"); + _queryBuilder.Append($"('{key}'){ODataQuerySeparators.QueryStringBegin}"); return new ODataQueryParameterKey(_queryBuilder); } public IODataQueryParameterList ByList() { - _queryBuilder.Append(Constants.QueryStringBegin); + _queryBuilder.Append(ODataQuerySeparators.QueryStringBegin); return new ODataQueryParameterList(_queryBuilder); } From b26812baf1f0943f1a9d936ecebbce387dc0bb68 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Mon, 11 May 2020 17:01:35 +0300 Subject: [PATCH 11/76] #ZEXSM#odata functions --- .../Builders/ODataQueryBuilder.cs | 4 +- .../Constants/ODataQueryParameters.cs | 14 +-- .../Constants/ODataQuerySeparators.cs | 24 ++--- .../Constants/ODataQuerySorts.cs | 4 +- .../Extensions/BinaryExpressionExtensions.cs | 76 +------------ .../ConstantExpressionExtensions.cs | 3 + .../Extensions/ExpressionExtensions.cs | 15 +++ .../Extensions/MemberExpressionExtensions.cs | 59 +++++++---- .../MethodCallExpressionExtensions.cs | 100 +++++++++--------- .../Extensions/NewExpressionExtensions.cs | 29 ++++- ...oExtensions.cs => ReflectionExtensions.cs} | 5 +- .../Functions/IODataQueryFunction.cs | 18 ++++ .../Parameters/IODataQueryParameterList.cs | 5 +- .../Nested/ODataQueryNestedParameter.cs | 14 +-- .../Nested/ODataQueryNestedParameterBase.cs | 2 +- .../Parameters/ODataQueryParameter.cs | 6 +- .../Parameters/ODataQueryParameterKey.cs | 6 +- .../Parameters/ODataQueryParameterList.cs | 28 +++-- .../Resourses/ODataQueryResource.cs | 6 +- .../ODataQueryBuilderByListTest.cs | 45 +++++--- 20 files changed, 246 insertions(+), 217 deletions(-) rename src/OData.QueryBuilder/Extensions/{MemberInfoExtensions.cs => ReflectionExtensions.cs} (80%) create mode 100644 src/OData.QueryBuilder/Functions/IODataQueryFunction.cs diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index 54da2ac9..0a2d31bf 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -11,10 +11,10 @@ public class ODataQueryBuilder : IODataQueryBuilder private readonly string _baseUrl; public ODataQueryBuilder(Uri baseUrl) => - _baseUrl = $"{baseUrl.OriginalString.TrimEnd(ODataQuerySeparators.SlashCharSeparator)}{ODataQuerySeparators.SlashStringSeparator}"; + _baseUrl = $"{baseUrl.OriginalString.TrimEnd(ODataQuerySeparators.SlashChar)}{ODataQuerySeparators.SlashString}"; public ODataQueryBuilder(string baseUrl) => - _baseUrl = $"{baseUrl.TrimEnd(ODataQuerySeparators.SlashCharSeparator)}{ODataQuerySeparators.SlashStringSeparator}"; + _baseUrl = $"{baseUrl.TrimEnd(ODataQuerySeparators.SlashChar)}{ODataQuerySeparators.SlashString}"; public IODataQueryResource For(Expression> entityResource) => new ODataQueryResource($"{_baseUrl}{entityResource.Body.ToODataQuery(string.Empty)}"); diff --git a/src/OData.QueryBuilder/Constants/ODataQueryParameters.cs b/src/OData.QueryBuilder/Constants/ODataQueryParameters.cs index f9976f9b..769c1cdd 100644 --- a/src/OData.QueryBuilder/Constants/ODataQueryParameters.cs +++ b/src/OData.QueryBuilder/Constants/ODataQueryParameters.cs @@ -2,12 +2,12 @@ { internal struct ODataQueryParameters { - public const string QueryParameterSelect = "$select"; - public const string QueryParameterExpand = "$expand"; - public const string QueryParameterFilter = "$filter"; - public const string QueryParameterOrderBy = "$orderby"; - public const string QueryParameterTop = "$top"; - public const string QueryParameterSkip = "$skip"; - public const string QueryParameterCount = "$count"; + public const string Select = "$select"; + public const string Expand = "$expand"; + public const string Filter = "$filter"; + public const string OrderBy = "$orderby"; + public const string Top = "$top"; + public const string Skip = "$skip"; + public const string Count = "$count"; } } diff --git a/src/OData.QueryBuilder/Constants/ODataQuerySeparators.cs b/src/OData.QueryBuilder/Constants/ODataQuerySeparators.cs index 59898db2..cc81be5e 100644 --- a/src/OData.QueryBuilder/Constants/ODataQuerySeparators.cs +++ b/src/OData.QueryBuilder/Constants/ODataQuerySeparators.cs @@ -2,17 +2,17 @@ { internal struct ODataQuerySeparators { - public const string QueryStringSeparator = "&"; - public const char QueryCharSeparator = '&'; - public const string QueryStringNestedSeparator = ";"; - public const char QueryCharNestedSeparator = ';'; - public const string QueryStringBegin = "?"; - public const char QueryCharBegin = '?'; - public const string QueryStringEqualSign = "="; - public const char QueryCharEqualSign = '='; - public const string SlashStringSeparator = "/"; - public const char SlashCharSeparator = '/'; - public const string CommaStringSeparator = ","; - public const char DotCharSeparator = '.'; + public const string MainString = "&"; + public const char MainChar = '&'; + public const string NestedString = ";"; + public const char NestedChar = ';'; + public const string BeginString = "?"; + public const char BeginChar = '?'; + public const string EqualSignString = "="; + public const char EqualSignChar = '='; + public const string SlashString = "/"; + public const char SlashChar = '/'; + public const string CommaString = ","; + public const char DotChar = '.'; } } diff --git a/src/OData.QueryBuilder/Constants/ODataQuerySorts.cs b/src/OData.QueryBuilder/Constants/ODataQuerySorts.cs index d46ca8b6..2b5858f5 100644 --- a/src/OData.QueryBuilder/Constants/ODataQuerySorts.cs +++ b/src/OData.QueryBuilder/Constants/ODataQuerySorts.cs @@ -2,7 +2,7 @@ { internal struct ODataQuerySorts { - public const string QuerySortAsc = "asc"; - public const string QuerySortDesc = "desc"; + public const string Asc = "asc"; + public const string Desc = "desc"; } } diff --git a/src/OData.QueryBuilder/Extensions/BinaryExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/BinaryExpressionExtensions.cs index 4fdb8c16..12b56121 100644 --- a/src/OData.QueryBuilder/Extensions/BinaryExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/BinaryExpressionExtensions.cs @@ -1,7 +1,4 @@ -using OData.QueryBuilder.Constants; -using System; -using System.Linq; -using System.Linq.Expressions; +using System.Linq.Expressions; namespace OData.QueryBuilder.Extensions { @@ -9,12 +6,6 @@ internal static class BinaryExpressionExtensions { public static string ToODataQuery(this BinaryExpression binaryExpression, string queryString) { - var funcDateQuery = binaryExpression.ToODataQueryFunctionDate(); - if (!string.IsNullOrEmpty(funcDateQuery)) - { - return funcDateQuery; - } - var leftQueryString = binaryExpression.Left.ToODataQuery(queryString); var rightQueryString = binaryExpression.Right.ToODataQuery(queryString); @@ -30,70 +21,5 @@ public static string ToODataQuery(this BinaryExpression binaryExpression, string return $"{leftQueryString} {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryString}"; } - - public static string ToODataQueryFunctionDate(this BinaryExpression binaryExpression) - { - if (binaryExpression.Left.Type == typeof(DateTime) || binaryExpression.Left.Type == typeof(DateTimeOffset) - || binaryExpression.Left.Type == typeof(DateTime?) || binaryExpression.Left.Type == typeof(DateTimeOffset?)) - { - var leftExpression = binaryExpression.Left as MemberExpression ?? - (binaryExpression.Left as UnaryExpression).Operand as MemberExpression ?? - ((binaryExpression.Left as UnaryExpression).Operand as UnaryExpression).Operand as MemberExpression; - - if (leftExpression != default(MemberExpression)) - { - if (leftExpression.Member.Name == nameof(DateTime.Date)) - { - var leftQuery = leftExpression.Expression.ToODataQuery(string.Empty); - - switch (binaryExpression.Right) - { - case NewExpression rightNewExpression: - var rightQueryNew = ((DateTime)rightNewExpression.Constructor - .Invoke(rightNewExpression.Arguments.Select(s => ((ConstantExpression)s).Value).ToArray())) - .ToString("yyyy-MM-dd"); - - return $"{ODataQueryFunctions.Date}({leftQuery}) {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryNew}"; - case MemberExpression rightMemberExpression: - var rightQueryMember = ((DateTime)rightMemberExpression.GetMemberValue()) - .ToString("yyyy-MM-dd"); - - return $"{ODataQueryFunctions.Date}({leftQuery}) {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryMember}"; - case ConstantExpression rightConstantExpression: - var rightQueryConstant = rightConstantExpression.ToODataQuery(); - - return $"{ODataQueryFunctions.Date}({leftQuery}) {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryConstant}"; - } - } - else - { - var leftQuery = leftExpression.ToODataQuery(string.Empty); - - switch (binaryExpression.Right) - { - case UnaryExpression rightUnaryExpression: - var memberExpression = rightUnaryExpression.Operand as MemberExpression ?? - (rightUnaryExpression.Operand as UnaryExpression).Operand as MemberExpression; - - var rightQueryUnary = ((DateTime)memberExpression.GetMemberValue()) - .ToString("O"); - - return $"{leftQuery} {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryUnary}"; - case MemberExpression rightMemberExpression: - var rightQueryMember = ((DateTime)rightMemberExpression.GetMemberValue()) - .ToString("O"); - - return $"{leftQuery} {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryMember}"; - case ConstantExpression rightConstantExpression: - var rightQueryConstant = rightConstantExpression.ToODataQuery(); - - return $"{leftQuery} {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryConstant}"; - } - } - } - } - - return string.Empty; - } } } diff --git a/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs index f7a3ffeb..db091e60 100644 --- a/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs @@ -20,5 +20,8 @@ public static string ToODataQuery(this ConstantExpression constantExpression) return "null"; } } + + public static object GetValue(this ConstantExpression constantExpression) => + constantExpression.Value; } } diff --git a/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs index d0ae9ab2..6881fb96 100644 --- a/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs @@ -33,5 +33,20 @@ public static string ToODataQuery(this Expression expression, string queryString return string.Empty; } } + + public static object GetValue(this Expression expression) + { + switch (expression) + { + case MemberExpression memberExpression: + return memberExpression.GetValue(); + + case ConstantExpression constantExpression: + return constantExpression.GetValue(); + + default: + return default; + } + } } } diff --git a/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs index 30924c70..8b11d6ed 100644 --- a/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs @@ -1,38 +1,34 @@ -using System.Linq.Expressions; +using System; +using System.Linq.Expressions; namespace OData.QueryBuilder.Extensions { internal static class MemberExpressionExtensions { - public static object GetMemberValue(this MemberExpression memberExpression) + public static string ToODataQuery(this MemberExpression memberExpression, string queryString) { - if (memberExpression.Expression is ConstantExpression ce) - { - return memberExpression.Member.GetValue(ce.Value); - } + var memberExpressionValue = memberExpression.GetValue(); - if (memberExpression.Expression is MemberExpression me) + if (memberExpressionValue != default) { - return memberExpression.Member.GetValue(GetMemberValue(me)); - } - - return memberExpression.Member.GetValue(); - } + if (memberExpressionValue is string @string) + { + return $"'{@string}'"; + } - public static string ToODataQuery(this MemberExpression memberExpression, string queryString) - { - var memberExpressionValue = memberExpression.GetMemberValue(); + if (memberExpressionValue is bool @bool) + { + return $"{@bool}".ToLower(); + } - if (memberExpressionValue != default(object)) - { - if (memberExpressionValue is string) + if (memberExpressionValue is DateTime dateTime) { - return $"'{memberExpressionValue}'"; + return $"{dateTime:s}Z"; } - if (memberExpressionValue is bool) + if (memberExpressionValue is DateTimeOffset dateTimeOffset) { - return $"{memberExpressionValue}".ToLower(); + return $"{dateTimeOffset:s}Z"; } return $"{memberExpressionValue}"; @@ -45,7 +41,26 @@ public static string ToODataQuery(this MemberExpression memberExpression, string return memberExpression.Member.Name; } - return $"{parentMemberExpressionQuery}/{memberExpression.Member.Name}"; + return memberExpression.Member.DeclaringType.IsNullableType() ? + parentMemberExpressionQuery + : + $"{parentMemberExpressionQuery}/{memberExpression.Member.Name}" + ; + } + + public static object GetValue(this MemberExpression memberExpression) + { + if (memberExpression.Expression is ConstantExpression ce) + { + return memberExpression.Member.GetValue(ce.Value); + } + + if (memberExpression.Expression is MemberExpression me) + { + return memberExpression.Member.GetValue(GetValue(me)); + } + + return memberExpression.Member.GetValue(); } } } diff --git a/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs index 3e188318..a8d17976 100644 --- a/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs @@ -1,4 +1,5 @@ using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Functions; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -10,72 +11,67 @@ internal static class MethodCallExpressionExtensions public static string ToODataQuery(this MethodCallExpression methodCallExpression, string queryString) { var methodName = methodCallExpression.Method.Name; + var resource = default(object); + var filter = default(string); - if (methodName == nameof(Enumerable.All)) + switch (methodName) { - var resource = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); - var filter = methodCallExpression.Arguments[1]?.ToODataQuery(queryString); + case nameof(IODataQueryFunction.Date): + filter = methodCallExpression.Arguments[0]?.ToODataQuery(queryString) ?? string.Empty; - return $"{resource}/{ODataQueryFunctions.All}({filter})"; - } - - if (methodName == nameof(Enumerable.Any)) - { - var resource = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); - var filter = methodCallExpression.Arguments[1]?.ToODataQuery(queryString); + return $"{methodName.ToLower()}({filter})"; - return $"{resource}/{ODataQueryFunctions.Any}({filter})"; - } + case nameof(Enumerable.All): + case nameof(Enumerable.Any): + resource = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); + filter = methodCallExpression.Arguments[1]?.ToODataQuery(queryString); - if (methodName == nameof(Enumerable.Contains)) - { - var resource = default(object); - var filter = default(string); + return $"{resource}/{methodName.ToLower()}({filter})"; - if (methodCallExpression.Object == default(Expression)) - { - resource = (methodCallExpression.Arguments[0] as MemberExpression).GetMemberValue(); - filter = methodCallExpression.Arguments[1].ToODataQuery(queryString); - } - else if (methodCallExpression.Object is MemberExpression) - { - resource = (methodCallExpression.Object as MemberExpression).GetMemberValue() ?? - methodCallExpression.Object.ToODataQuery(string.Empty); - - filter = methodCallExpression.Arguments[0].ToODataQuery(queryString); - } - else if (methodCallExpression.Object is MethodCallExpression) - { - resource = methodCallExpression.Object.ToODataQuery(string.Empty); - filter = methodCallExpression.Arguments[0].ToODataQuery(string.Empty); - } - - var inSequence = resource.GetInSequence(); + case nameof(Enumerable.Contains): + if (methodCallExpression.Object == default(Expression)) + { + resource = (methodCallExpression.Arguments[0] as MemberExpression).GetValue(); + filter = methodCallExpression.Arguments[1].ToODataQuery(queryString); + } + else if (methodCallExpression.Object is MemberExpression) + { + resource = (methodCallExpression.Object as MemberExpression).GetValue() ?? + methodCallExpression.Object.ToODataQuery(string.Empty); - if (inSequence != default) - { - if (!string.IsNullOrEmpty(inSequence)) + filter = methodCallExpression.Arguments[0].ToODataQuery(queryString); + } + else if (methodCallExpression.Object is MethodCallExpression) { - return $"{filter} {inSequence}"; + resource = methodCallExpression.Object.ToODataQuery(string.Empty); + filter = methodCallExpression.Arguments[0].ToODataQuery(string.Empty); } - else + + var inSequence = resource.GetInSequence(); + + if (inSequence != default) { - return $"{ODataQueryFunctions.Substringof}({filter},{resource})"; + if (!string.IsNullOrEmpty(inSequence)) + { + return $"{filter} {inSequence}"; + } + else + { + return $"{ODataQueryFunctions.Substringof}({filter},{resource})"; + } } - } - } - if (methodName == nameof(string.ToUpper)) - { - return $"{ODataQueryFunctions.Toupper}({methodCallExpression.Object.ToODataQuery(string.Empty)})"; - } + return string.Empty; - if (methodName == nameof(ToString)) - { - return methodCallExpression.Object.ToODataQuery(string.Empty); - } + case nameof(string.ToUpper): + return $"{ODataQueryFunctions.Toupper}({methodCallExpression.Object.ToODataQuery(string.Empty)})"; - return string.Empty; + case nameof(ToString): + return methodCallExpression.Object.ToODataQuery(string.Empty); + + default: + return string.Empty; + } } private static string GetInSequence(this object arrayObj) diff --git a/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs index 5bc793be..0b84485c 100644 --- a/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs @@ -1,4 +1,5 @@ -using System.Linq.Expressions; +using System; +using System.Linq.Expressions; namespace OData.QueryBuilder.Extensions { @@ -6,6 +7,32 @@ internal static class NewExpressionExtensions { public static string ToODataQuery(this NewExpression newExpression) { + if (newExpression.Members == default) + { + var arguments = new object[newExpression.Arguments.Count]; + + for (var i = 0; i < newExpression.Arguments.Count; i++) + { + arguments[i] = newExpression.Arguments[i].GetValue(); + } + + if (newExpression.Type == typeof(DateTime)) + { + var datetime = newExpression.Constructor.Invoke(arguments); + + return $"{datetime:s}Z"; + } + + if (newExpression.Type == typeof(DateTimeOffset)) + { + var datetime = newExpression.Constructor.Invoke(arguments); + + return $"{datetime:s}Z"; + } + + return string.Empty; + } + var names = new string[newExpression.Members.Count]; for (var i = 0; i < newExpression.Members.Count; i++) diff --git a/src/OData.QueryBuilder/Extensions/MemberInfoExtensions.cs b/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs similarity index 80% rename from src/OData.QueryBuilder/Extensions/MemberInfoExtensions.cs rename to src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs index 9c67dbc0..463d8ef2 100644 --- a/src/OData.QueryBuilder/Extensions/MemberInfoExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs @@ -3,7 +3,7 @@ namespace OData.QueryBuilder.Extensions { - internal static class MemberInfoExtensions + internal static class ReflectionExtensions { public static object GetValue(this MemberInfo memberInfo, object obj = default) { @@ -24,5 +24,8 @@ public static object GetValue(this MemberInfo memberInfo, object obj = default) return default; } } + + public static bool IsNullableType(this Type type) => + Nullable.GetUnderlyingType(type) != default; } } diff --git a/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs b/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs new file mode 100644 index 00000000..b31800d3 --- /dev/null +++ b/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +namespace OData.QueryBuilder.Functions +{ + public interface IODataQueryFunction + { + DateTime Date(DateTimeOffset dateTimeOffset); + + string Substringof(); + + IEnumerable In(IEnumerable enumerable); + + IEnumerable In(IEnumerable enumerable); + + IEnumerable In(IEnumerable enumerable); + } +} diff --git a/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs index 22cd723a..59bb5be5 100644 --- a/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs @@ -1,13 +1,16 @@ using OData.QueryBuilder.Builders.Nested; +using OData.QueryBuilder.Functions; using System; using System.Linq.Expressions; namespace OData.QueryBuilder.Parameters { - public interface IODataQueryParameterList: IODataQueryParameter + public interface IODataQueryParameterList : IODataQueryParameter { IODataQueryParameterList Filter(Expression> entityFilter); + IODataQueryParameterList Filter(Expression> entityFilter); + IODataQueryParameterList Expand(Expression> entityExpand); IODataQueryParameterList Expand(Action> entityExpandNested); diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs index 72940497..21e29d8a 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs @@ -18,7 +18,7 @@ public IODataQueryNestedParameter Expand(Expression Expand(Action Filter(Expression { var query = entityNestedFilter.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{ODataQueryParameters.QueryParameterFilter}{ODataQuerySeparators.QueryStringEqualSign}{query}{ODataQuerySeparators.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.NestedString}"); return this; } @@ -47,7 +47,7 @@ public IODataQueryNestedParameter OrderBy(Expression OrderByDescending(Expression Select(Expression Top(int value) { - _queryBuilder.Append($"{ODataQueryParameters.QueryParameterTop}{ODataQuerySeparators.QueryStringEqualSign}{value}{ODataQuerySeparators.QueryStringNestedSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.Top}{ODataQuerySeparators.EqualSignString}{value}{ODataQuerySeparators.NestedString}"); return this; } diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs index ac56d3b9..2b92f256 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs @@ -10,6 +10,6 @@ public abstract class ODataQueryNestedParameterBase public ODataQueryNestedParameterBase(StringBuilder queryBuilder) => _queryBuilder = queryBuilder; - public string Query => _queryBuilder.ToString().Trim(ODataQuerySeparators.QueryCharNestedSeparator); + public string Query => _queryBuilder.ToString().Trim(ODataQuerySeparators.NestedChar); } } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs index 5170a315..492c3d20 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs @@ -15,13 +15,13 @@ public ODataQueryParameter(StringBuilder queryBuilder) => public Dictionary ToDictionary() { var odataOperators = _queryBuilder.ToString() - .Split(new char[2] { ODataQuerySeparators.QueryCharBegin, ODataQuerySeparators.QueryCharSeparator }, StringSplitOptions.RemoveEmptyEntries); + .Split(new char[2] { ODataQuerySeparators.BeginChar, ODataQuerySeparators.MainChar }, StringSplitOptions.RemoveEmptyEntries); var dictionary = new Dictionary(odataOperators.Length - 1); for (var step = 1; step < odataOperators.Length; step++) { - var odataOperator = odataOperators[step].Split(ODataQuerySeparators.QueryCharEqualSign); + var odataOperator = odataOperators[step].Split(ODataQuerySeparators.EqualSignChar); dictionary.Add(odataOperator[0], odataOperator[1]); } @@ -29,6 +29,6 @@ public Dictionary ToDictionary() return dictionary; } - public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd(ODataQuerySeparators.QueryCharSeparator)); + public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd(ODataQuerySeparators.MainChar)); } } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs index 148b3528..712b5fdd 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs @@ -18,7 +18,7 @@ public IODataQueryParameterKey Expand(Expression> { var query = entityExpand.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{ODataQueryParameters.QueryParameterExpand}{ODataQuerySeparators.QueryStringEqualSign}{query}{ODataQuerySeparators.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; } @@ -29,7 +29,7 @@ public IODataQueryParameterKey Expand(Action Select(Expression> { var query = entitySelect.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{ODataQueryParameters.QueryParameterSelect}{ODataQuerySeparators.QueryStringEqualSign}{query}{ODataQuerySeparators.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs index bf18bd5d..ddef582f 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs @@ -1,6 +1,7 @@ using OData.QueryBuilder.Builders.Nested; using OData.QueryBuilder.Constants; using OData.QueryBuilder.Extensions; +using OData.QueryBuilder.Functions; using System; using System.Linq.Expressions; using System.Text; @@ -18,7 +19,16 @@ public IODataQueryParameterList Filter(Expression> { var query = entityFilter.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{ODataQueryParameters.QueryParameterFilter}{ODataQuerySeparators.QueryStringEqualSign}{query}{ODataQuerySeparators.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); + + return this; + } + + public IODataQueryParameterList Filter(Expression> entityFilter) + { + var query = entityFilter.Body.ToODataQuery(string.Empty); + + _queryBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; } @@ -27,7 +37,7 @@ public IODataQueryParameterList Expand(Expression { var query = entityExpand.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{ODataQueryParameters.QueryParameterExpand}{ODataQuerySeparators.QueryStringEqualSign}{query}{ODataQuerySeparators.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; } @@ -38,7 +48,7 @@ public IODataQueryParameterList Expand(Action Select(Expression { var query = entitySelect.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{ODataQueryParameters.QueryParameterSelect}{ODataQuerySeparators.QueryStringEqualSign}{query}{ODataQuerySeparators.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; } @@ -56,7 +66,7 @@ public IODataQueryParameterList OrderBy(Expression OrderByDescending(Expression Skip(int value) { - _queryBuilder.Append($"{ODataQueryParameters.QueryParameterSkip}{ODataQuerySeparators.QueryStringEqualSign}{value}{ODataQuerySeparators.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.Skip}{ODataQuerySeparators.EqualSignString}{value}{ODataQuerySeparators.MainString}"); return this; } public IODataQueryParameterList Top(int value) { - _queryBuilder.Append($"{ODataQueryParameters.QueryParameterTop}{ODataQuerySeparators.QueryStringEqualSign}{value}{ODataQuerySeparators.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.Top}{ODataQuerySeparators.EqualSignString}{value}{ODataQuerySeparators.MainString}"); return this; } public IODataQueryParameterList Count(bool value = true) { - _queryBuilder.Append($"{ODataQueryParameters.QueryParameterCount}{ODataQuerySeparators.QueryStringEqualSign}{value.ToString().ToLower()}{ODataQuerySeparators.QueryStringSeparator}"); + _queryBuilder.Append($"{ODataQueryParameters.Count}{ODataQuerySeparators.EqualSignString}{value.ToString().ToLower()}{ODataQuerySeparators.MainString}"); return this; } diff --git a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs b/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs index 22731db1..baa777ce 100644 --- a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs +++ b/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs @@ -13,21 +13,21 @@ public ODataQueryResource(string resourceUrl) => public IODataQueryParameterKey ByKey(int key) { - _queryBuilder.Append($"({key}){ODataQuerySeparators.QueryStringBegin}"); + _queryBuilder.Append($"({key}){ODataQuerySeparators.BeginString}"); return new ODataQueryParameterKey(_queryBuilder); } public IODataQueryParameterKey ByKey(string key) { - _queryBuilder.Append($"('{key}'){ODataQuerySeparators.QueryStringBegin}"); + _queryBuilder.Append($"('{key}'){ODataQuerySeparators.BeginString}"); return new ODataQueryParameterKey(_queryBuilder); } public IODataQueryParameterList ByList() { - _queryBuilder.Append(ODataQuerySeparators.QueryStringBegin); + _queryBuilder.Append(ODataQuerySeparators.BeginString); return new ODataQueryParameterList(_queryBuilder); } diff --git a/test/OData.QueryBuilder.Test/ODataQueryBuilderByListTest.cs b/test/OData.QueryBuilder.Test/ODataQueryBuilderByListTest.cs index 2e05762c..c71e075e 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryBuilderByListTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryBuilderByListTest.cs @@ -232,26 +232,39 @@ public void ODataQueryBuilderList_Expand_Filter_Select_OrderBy_OrderByDescending [Fact(DisplayName = "(ODataQueryBuilderList) Function Date => Success")] public void ODataQueryBuilderList_Function_Date_Success() { - var constCurrentDateToday = new DateTime(2019, 2, 9); - var constCurrentDateNow = new DateTime(2019, 2, 9, 1, 2, 4); - var newObject = new ODataTypeEntity { ODataKind = new ODataKindEntity { EndDate = constCurrentDateToday } }; + var currentDateToday = new DateTime(2019, 2, 9); + var currentDateNow = new DateTime(2019, 2, 9, 1, 2, 4); + var newObject = new ODataTypeEntity { ODataKind = new ODataKindEntity { EndDate = currentDateToday } }; var uri = _odataQueryBuilder .For(s => s.ODataType) .ByList() - .Filter(s => - s.ODataKind.OpenDate.Date == constCurrentDateNow - && s.ODataKind.OpenDate == constCurrentDateToday + .Filter((s, f) => + f.Date(s.ODataKind.OpenDate) == currentDateNow + && s.ODataKind.OpenDate == currentDateToday && s.ODataKind.OpenDate == DateTime.Today - && s.Open.Date == DateTime.Today + && f.Date(s.Open) == DateTime.Today + && f.Date(s.Open) == DateTimeOffset.Now && s.Open == DateTime.Today - && s.Open == constCurrentDateToday - && s.Open.Date == newObject.ODataKind.EndDate - && s.ODataKind.OpenDate.Date == new DateTime(2019, 7, 9) - && ((DateTime)s.BeginDate).Date == DateTime.Today) + && s.Open == currentDateToday + && f.Date(s.Open) == newObject.ODataKind.EndDate + && f.Date(s.ODataKind.OpenDate) == new DateTime(2019, 7, 9) + && f.Date(s.ODataKind.OpenDate) == new DateTimeOffset(currentDateToday) + && f.Date((DateTimeOffset)s.BeginDate) == DateTime.Today) .ToUri(); - uri.OriginalString.Should().Be($"http://mock/odata/ODataType?$filter=date(ODataKind/OpenDate) eq 2019-02-09 and ODataKind/OpenDate eq 2019-02-09T00:00:00.0000000 and ODataKind/OpenDate eq {DateTime.Today.ToString("O")} and date(Open) eq {DateTime.Today.ToString("yyyy-MM-dd")} and Open eq {DateTime.Today.ToString("O")} and Open eq 2019-02-09T00:00:00.0000000 and date(Open) eq 2019-02-09 and date(ODataKind/OpenDate) eq 2019-07-09 and date(BeginDate) eq {DateTime.Today.ToString("yyyy-MM-dd")}"); + uri.OriginalString.Should().Be($"http://mock/odata/ODataType?$filter=" + + $"date(ODataKind/OpenDate) eq 2019-02-09T01:02:04Z " + + $"and ODataKind/OpenDate eq 2019-02-09T00:00:00Z " + + $"and ODataKind/OpenDate eq {DateTime.Today:s}Z " + + $"and date(Open) eq {DateTime.Today:s}Z " + + $"and date(Open) eq {DateTimeOffset.Now:s}Z " + + $"and Open eq {DateTime.Today:s}Z " + + $"and Open eq 2019-02-09T00:00:00Z " + + $"and date(Open) eq 2019-02-09T00:00:00Z " + + $"and date(ODataKind/OpenDate) eq 2019-07-09T00:00:00Z " + + $"and date(ODataKind/OpenDate) eq 2019-02-09T00:00:00Z " + + $"and date(BeginDate) eq {DateTime.Today:s}Z"); } [Fact(DisplayName = "(ODataQueryBuilderList) Operator IN => Success")] @@ -353,14 +366,14 @@ public void ODataQueryBuilderList_Filter_Brackets_Success() var uri = _odataQueryBuilder .For(s => s.ODataType) .ByList() - .Filter(s => s.IdRule == constValue + .Filter((s, f) => s.IdRule == constValue && s.IsActive - && (((DateTimeOffset)s.EndDate).Date == default(DateTimeOffset?) || s.EndDate > DateTime.Today) - && (((DateTime)s.BeginDate).Date != default(DateTime?) || ((DateTime)s.BeginDate).Date <= DateTime.Today) + && (f.Date(s.EndDate.Value) == default(DateTimeOffset?) || s.EndDate > DateTime.Today) + && (f.Date((DateTimeOffset)s.BeginDate) != default(DateTime?) || f.Date((DateTime)s.BeginDate) <= DateTime.Now) && constStrIds.Contains(s.ODataKind.ODataCode.Code)) .ToUri(); - uri.OriginalString.Should().Be($"http://mock/odata/ODataType?$filter=IdRule eq 3 and IsActive and date(EndDate) eq null or EndDate gt {DateTime.Today.ToString("O")} and date(BeginDate) ne null or date(BeginDate) le {DateTime.Today.ToString("yyyy-MM-dd")} and ODataKind/ODataCode/Code in ('123','512')"); + uri.OriginalString.Should().Be($"http://mock/odata/ODataType?$filter=IdRule eq 3 and IsActive and date(EndDate) eq null or EndDate gt {DateTime.Today:s}Z and date(BeginDate) ne null or date(BeginDate) le {DateTime.Now:s}Z and ODataKind/ODataCode/Code in ('123','512')"); } [Theory(DisplayName = "(ODataQueryBuilderList) Count value => Success")] From 3ec4b665e3150458f795c0d678e5396c93451330 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Mon, 11 May 2020 17:14:15 +0300 Subject: [PATCH 12/76] #ZEXSM#fix --- .../Extensions/MethodCallExpressionExtensions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs index a8d17976..6ba2b29c 100644 --- a/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs @@ -80,6 +80,7 @@ private static string GetInSequence(this object arrayObj) { return default; } + if (arrayObj is IEnumerable) { var inSequenceInt = string.Join(",", arrayObj as IEnumerable); From e3c6f0bda7cb1676a87901e34dbbdc3cb49ee53b Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Mon, 11 May 2020 17:47:24 +0300 Subject: [PATCH 13/76] #ZEX#review#add expressions --- .../Nested/ODataQueryNestedBuilder.cs | 10 ++++----- .../Constants/ODataQueryFunctions.cs | 5 +++++ .../Constants/ODataQueryParameters.cs | 6 +++++ .../Constants/ODataQuerySeparators.cs | 11 ++++++++++ .../Constants/ODataQuerySorts.cs | 1 + .../Expressions/ExpandExpression.cs | 8 +++++++ .../Expressions/FilterExpression.cs | 8 +++++++ .../OrderByDescendingExpression.cs | 8 +++++++ .../Expressions/OrderByExpression.cs | 8 +++++++ .../Expressions/SelectExpression.cs | 8 +++++++ .../Nested/ODataQueryNestedParameter.cs | 14 ++++++------ .../Nested/ODataQueryNestedParameterBase.cs | 6 ++--- .../Parameters/ODataQueryParameter.cs | 16 +++++++++----- .../Parameters/ODataQueryParameterKey.cs | 8 +++---- .../Parameters/ODataQueryParameterList.cs | 22 +++++++++---------- .../Resourses/ODataQueryResource.cs | 16 +++++++------- 16 files changed, 111 insertions(+), 44 deletions(-) create mode 100644 src/OData.QueryBuilder/Expressions/ExpandExpression.cs create mode 100644 src/OData.QueryBuilder/Expressions/FilterExpression.cs create mode 100644 src/OData.QueryBuilder/Expressions/OrderByDescendingExpression.cs create mode 100644 src/OData.QueryBuilder/Expressions/OrderByExpression.cs create mode 100644 src/OData.QueryBuilder/Expressions/SelectExpression.cs diff --git a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs index f308db4e..4b1f9bc3 100644 --- a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs @@ -8,23 +8,23 @@ namespace OData.QueryBuilder.Builders.Nested { public class ODataQueryNestedBuilder : IODataQueryNestedBuilder { - private readonly StringBuilder _queryBuilder; + private readonly StringBuilder _stringBuilder; private ODataQueryNestedParameterBase _odataQueryNestedParameter; public ODataQueryNestedBuilder() => - _queryBuilder = new StringBuilder(); + _stringBuilder = new StringBuilder(); - public string Query => $"{_queryBuilder}({_odataQueryNestedParameter.Query})"; + public string Query => $"{_stringBuilder}({_odataQueryNestedParameter.Query})"; public IODataQueryNestedParameter For(Expression> nestedEntityExpand) { if (!string.IsNullOrEmpty(_odataQueryNestedParameter?.Query)) { - _queryBuilder.Append($"({_odataQueryNestedParameter.Query}),{nestedEntityExpand.Body.ToODataQuery(string.Empty)}"); + _stringBuilder.Append($"({_odataQueryNestedParameter.Query}),{nestedEntityExpand.Body.ToODataQuery(string.Empty)}"); } else { - _queryBuilder.Append($"{nestedEntityExpand.Body.ToODataQuery(string.Empty)}"); + _stringBuilder.Append($"{nestedEntityExpand.Body.ToODataQuery(string.Empty)}"); } _odataQueryNestedParameter = new ODataQueryNestedParameter(); diff --git a/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs b/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs index f4a79ed3..824c15e3 100644 --- a/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs +++ b/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs @@ -3,10 +3,15 @@ internal struct ODataQueryFunctions { public const string Any = "any"; + public const string All = "all"; + public const string Date = "date"; + public const string Substringof = "substringof"; + public const string Toupper = "toupper"; + public const string In = "in"; } } diff --git a/src/OData.QueryBuilder/Constants/ODataQueryParameters.cs b/src/OData.QueryBuilder/Constants/ODataQueryParameters.cs index 769c1cdd..b7282538 100644 --- a/src/OData.QueryBuilder/Constants/ODataQueryParameters.cs +++ b/src/OData.QueryBuilder/Constants/ODataQueryParameters.cs @@ -3,11 +3,17 @@ internal struct ODataQueryParameters { public const string Select = "$select"; + public const string Expand = "$expand"; + public const string Filter = "$filter"; + public const string OrderBy = "$orderby"; + public const string Top = "$top"; + public const string Skip = "$skip"; + public const string Count = "$count"; } } diff --git a/src/OData.QueryBuilder/Constants/ODataQuerySeparators.cs b/src/OData.QueryBuilder/Constants/ODataQuerySeparators.cs index cc81be5e..0fb6f856 100644 --- a/src/OData.QueryBuilder/Constants/ODataQuerySeparators.cs +++ b/src/OData.QueryBuilder/Constants/ODataQuerySeparators.cs @@ -3,16 +3,27 @@ internal struct ODataQuerySeparators { public const string MainString = "&"; + public const char MainChar = '&'; + public const string NestedString = ";"; + public const char NestedChar = ';'; + public const string BeginString = "?"; + public const char BeginChar = '?'; + public const string EqualSignString = "="; + public const char EqualSignChar = '='; + public const string SlashString = "/"; + public const char SlashChar = '/'; + public const string CommaString = ","; + public const char DotChar = '.'; } } diff --git a/src/OData.QueryBuilder/Constants/ODataQuerySorts.cs b/src/OData.QueryBuilder/Constants/ODataQuerySorts.cs index 2b5858f5..23be4685 100644 --- a/src/OData.QueryBuilder/Constants/ODataQuerySorts.cs +++ b/src/OData.QueryBuilder/Constants/ODataQuerySorts.cs @@ -3,6 +3,7 @@ internal struct ODataQuerySorts { public const string Asc = "asc"; + public const string Desc = "desc"; } } diff --git a/src/OData.QueryBuilder/Expressions/ExpandExpression.cs b/src/OData.QueryBuilder/Expressions/ExpandExpression.cs new file mode 100644 index 00000000..27a080fd --- /dev/null +++ b/src/OData.QueryBuilder/Expressions/ExpandExpression.cs @@ -0,0 +1,8 @@ +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Expressions +{ + public sealed class ExpandExpression : Expression + { + } +} diff --git a/src/OData.QueryBuilder/Expressions/FilterExpression.cs b/src/OData.QueryBuilder/Expressions/FilterExpression.cs new file mode 100644 index 00000000..5f8cce65 --- /dev/null +++ b/src/OData.QueryBuilder/Expressions/FilterExpression.cs @@ -0,0 +1,8 @@ +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Expressions +{ + public sealed class FilterExpression : Expression + { + } +} diff --git a/src/OData.QueryBuilder/Expressions/OrderByDescendingExpression.cs b/src/OData.QueryBuilder/Expressions/OrderByDescendingExpression.cs new file mode 100644 index 00000000..57aa1dcf --- /dev/null +++ b/src/OData.QueryBuilder/Expressions/OrderByDescendingExpression.cs @@ -0,0 +1,8 @@ +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Expressions +{ + public sealed class OrderByDescendingExpression : Expression + { + } +} diff --git a/src/OData.QueryBuilder/Expressions/OrderByExpression.cs b/src/OData.QueryBuilder/Expressions/OrderByExpression.cs new file mode 100644 index 00000000..3cabc7fd --- /dev/null +++ b/src/OData.QueryBuilder/Expressions/OrderByExpression.cs @@ -0,0 +1,8 @@ +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Expressions +{ + public sealed class OrderByExpression : Expression + { + } +} diff --git a/src/OData.QueryBuilder/Expressions/SelectExpression.cs b/src/OData.QueryBuilder/Expressions/SelectExpression.cs new file mode 100644 index 00000000..d0fb7dac --- /dev/null +++ b/src/OData.QueryBuilder/Expressions/SelectExpression.cs @@ -0,0 +1,8 @@ +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Expressions +{ + public sealed class SelectExpression : Expression + { + } +} diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs index 21e29d8a..0630984c 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs @@ -18,7 +18,7 @@ public IODataQueryNestedParameter Expand(Expression Expand(Action Filter(Expression { var query = entityNestedFilter.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.NestedString}"); + _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.NestedString}"); return this; } @@ -47,7 +47,7 @@ public IODataQueryNestedParameter OrderBy(Expression OrderByDescending(Expression Select(Expression Top(int value) { - _queryBuilder.Append($"{ODataQueryParameters.Top}{ODataQuerySeparators.EqualSignString}{value}{ODataQuerySeparators.NestedString}"); + _stringBuilder.Append($"{ODataQueryParameters.Top}{ODataQuerySeparators.EqualSignString}{value}{ODataQuerySeparators.NestedString}"); return this; } diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs index 2b92f256..8032c618 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs @@ -5,11 +5,11 @@ namespace OData.QueryBuilder.Parameters.Nested { public abstract class ODataQueryNestedParameterBase { - protected readonly StringBuilder _queryBuilder; + protected readonly StringBuilder _stringBuilder; public ODataQueryNestedParameterBase(StringBuilder queryBuilder) => - _queryBuilder = queryBuilder; + _stringBuilder = queryBuilder; - public string Query => _queryBuilder.ToString().Trim(ODataQuerySeparators.NestedChar); + public string Query => _stringBuilder.ToString().Trim(ODataQuerySeparators.NestedChar); } } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs index 492c3d20..7135fc42 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs @@ -5,16 +5,20 @@ namespace OData.QueryBuilder.Parameters { - public class ODataQueryParameter : IODataQueryParameter + public class ODataQueryParameter : IODataQueryParameter { - protected readonly StringBuilder _queryBuilder; + protected readonly StringBuilder _stringBuilder; + protected readonly string _resourceName; - public ODataQueryParameter(StringBuilder queryBuilder) => - _queryBuilder = queryBuilder; + public ODataQueryParameter(StringBuilder queryBuilder) + { + _stringBuilder = queryBuilder; + _resourceName = typeof(TEntity).Name; + } public Dictionary ToDictionary() { - var odataOperators = _queryBuilder.ToString() + var odataOperators = _stringBuilder.ToString() .Split(new char[2] { ODataQuerySeparators.BeginChar, ODataQuerySeparators.MainChar }, StringSplitOptions.RemoveEmptyEntries); var dictionary = new Dictionary(odataOperators.Length - 1); @@ -29,6 +33,6 @@ public Dictionary ToDictionary() return dictionary; } - public Uri ToUri() => new Uri(_queryBuilder.ToString().TrimEnd(ODataQuerySeparators.MainChar)); + public Uri ToUri() => new Uri(_stringBuilder.ToString().TrimEnd(ODataQuerySeparators.MainChar)); } } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs index 712b5fdd..164659b5 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs @@ -7,7 +7,7 @@ namespace OData.QueryBuilder.Parameters { - public class ODataQueryParameterKey : ODataQueryParameter, IODataQueryParameterKey + public class ODataQueryParameterKey : ODataQueryParameter, IODataQueryParameterKey { public ODataQueryParameterKey(StringBuilder queryBuilder) : base(queryBuilder) @@ -18,7 +18,7 @@ public IODataQueryParameterKey Expand(Expression> { var query = entityExpand.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); + _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; } @@ -29,7 +29,7 @@ public IODataQueryParameterKey Expand(Action Select(Expression> { var query = entitySelect.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); + _stringBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs index ddef582f..9bb60d4a 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs @@ -8,7 +8,7 @@ namespace OData.QueryBuilder.Parameters { - public class ODataQueryParameterList : ODataQueryParameter, IODataQueryParameterList + public class ODataQueryParameterList : ODataQueryParameter, IODataQueryParameterList { public ODataQueryParameterList(StringBuilder queryBuilder) : base(queryBuilder) @@ -19,7 +19,7 @@ public IODataQueryParameterList Filter(Expression> { var query = entityFilter.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); + _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; } @@ -28,7 +28,7 @@ public IODataQueryParameterList Filter(Expression Expand(Expression { var query = entityExpand.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); + _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; } @@ -48,7 +48,7 @@ public IODataQueryParameterList Expand(Action Select(Expression { var query = entitySelect.Body.ToODataQuery(string.Empty); - _queryBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); + _stringBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; } @@ -66,7 +66,7 @@ public IODataQueryParameterList OrderBy(Expression OrderByDescending(Expression Skip(int value) { - _queryBuilder.Append($"{ODataQueryParameters.Skip}{ODataQuerySeparators.EqualSignString}{value}{ODataQuerySeparators.MainString}"); + _stringBuilder.Append($"{ODataQueryParameters.Skip}{ODataQuerySeparators.EqualSignString}{value}{ODataQuerySeparators.MainString}"); return this; } public IODataQueryParameterList Top(int value) { - _queryBuilder.Append($"{ODataQueryParameters.Top}{ODataQuerySeparators.EqualSignString}{value}{ODataQuerySeparators.MainString}"); + _stringBuilder.Append($"{ODataQueryParameters.Top}{ODataQuerySeparators.EqualSignString}{value}{ODataQuerySeparators.MainString}"); return this; } public IODataQueryParameterList Count(bool value = true) { - _queryBuilder.Append($"{ODataQueryParameters.Count}{ODataQuerySeparators.EqualSignString}{value.ToString().ToLower()}{ODataQuerySeparators.MainString}"); + _stringBuilder.Append($"{ODataQueryParameters.Count}{ODataQuerySeparators.EqualSignString}{value.ToString().ToLower()}{ODataQuerySeparators.MainString}"); return this; } diff --git a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs b/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs index baa777ce..f78f99f8 100644 --- a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs +++ b/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs @@ -6,30 +6,30 @@ namespace OData.QueryBuilder.Resourses { public class ODataQueryResource : IODataQueryResource { - private readonly StringBuilder _queryBuilder; + private readonly StringBuilder _stringBuilder; public ODataQueryResource(string resourceUrl) => - _queryBuilder = new StringBuilder(resourceUrl); + _stringBuilder = new StringBuilder(resourceUrl); public IODataQueryParameterKey ByKey(int key) { - _queryBuilder.Append($"({key}){ODataQuerySeparators.BeginString}"); + _stringBuilder.Append($"({key}){ODataQuerySeparators.BeginString}"); - return new ODataQueryParameterKey(_queryBuilder); + return new ODataQueryParameterKey(_stringBuilder); } public IODataQueryParameterKey ByKey(string key) { - _queryBuilder.Append($"('{key}'){ODataQuerySeparators.BeginString}"); + _stringBuilder.Append($"('{key}'){ODataQuerySeparators.BeginString}"); - return new ODataQueryParameterKey(_queryBuilder); + return new ODataQueryParameterKey(_stringBuilder); } public IODataQueryParameterList ByList() { - _queryBuilder.Append(ODataQuerySeparators.BeginString); + _stringBuilder.Append(ODataQuerySeparators.BeginString); - return new ODataQueryParameterList(_queryBuilder); + return new ODataQueryParameterList(_stringBuilder); } } } From 1a35df9240b6423a0b23f7517b04f7e0fe15e482 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Mon, 11 May 2020 19:01:26 +0300 Subject: [PATCH 14/76] #ZEXSM#review --- .../Builders/Nested/ODataQueryNestedBuilder.cs | 14 +++++++------- .../Builders/ODataQueryBuilder.cs | 2 +- .../Expressions/ExpandExpression.cs | 2 +- .../Extensions/ExpressionExtensions.cs | 2 +- .../Functions/IODataQueryFunction.cs | 6 ++---- .../IODataQueryParameter.cs => IODataQuery.cs} | 4 ++-- .../ODataQueryParameter.cs => ODataQuery.cs} | 6 +++--- ...yNestedParameterBase.cs => ODataQueryNested.cs} | 6 +++--- .../Parameters/IODataQueryParameterKey.cs | 2 +- .../Parameters/IODataQueryParameterList.cs | 2 +- .../Parameters/Nested/ODataQueryNestedParameter.cs | 12 ++++++------ .../Parameters/ODataQueryParameterKey.cs | 6 +++--- .../Parameters/ODataQueryParameterList.cs | 14 +++++++------- 13 files changed, 38 insertions(+), 40 deletions(-) rename src/OData.QueryBuilder/{Parameters/IODataQueryParameter.cs => IODataQuery.cs} (63%) rename src/OData.QueryBuilder/{Parameters/ODataQueryParameter.cs => ODataQuery.cs} (86%) rename src/OData.QueryBuilder/{Parameters/Nested/ODataQueryNestedParameterBase.cs => ODataQueryNested.cs} (60%) diff --git a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs index 4b1f9bc3..1e5e547c 100644 --- a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs @@ -9,27 +9,27 @@ namespace OData.QueryBuilder.Builders.Nested public class ODataQueryNestedBuilder : IODataQueryNestedBuilder { private readonly StringBuilder _stringBuilder; - private ODataQueryNestedParameterBase _odataQueryNestedParameter; + private ODataQueryNested _odataQueryNested; public ODataQueryNestedBuilder() => _stringBuilder = new StringBuilder(); - public string Query => $"{_stringBuilder}({_odataQueryNestedParameter.Query})"; + public string Query => $"{_stringBuilder}({_odataQueryNested.Query})"; public IODataQueryNestedParameter For(Expression> nestedEntityExpand) { - if (!string.IsNullOrEmpty(_odataQueryNestedParameter?.Query)) + if (!string.IsNullOrEmpty(_odataQueryNested?.Query)) { - _stringBuilder.Append($"({_odataQueryNestedParameter.Query}),{nestedEntityExpand.Body.ToODataQuery(string.Empty)}"); + _stringBuilder.Append($"({_odataQueryNested.Query}),{nestedEntityExpand.Body.ToODataQuery()}"); } else { - _stringBuilder.Append($"{nestedEntityExpand.Body.ToODataQuery(string.Empty)}"); + _stringBuilder.Append($"{nestedEntityExpand.Body.ToODataQuery()}"); } - _odataQueryNestedParameter = new ODataQueryNestedParameter(); + _odataQueryNested = new ODataQueryNestedParameter(); - return _odataQueryNestedParameter as ODataQueryNestedParameter; + return _odataQueryNested as ODataQueryNestedParameter; } } } diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index 0a2d31bf..80c937d7 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -17,6 +17,6 @@ public ODataQueryBuilder(string baseUrl) => _baseUrl = $"{baseUrl.TrimEnd(ODataQuerySeparators.SlashChar)}{ODataQuerySeparators.SlashString}"; public IODataQueryResource For(Expression> entityResource) => - new ODataQueryResource($"{_baseUrl}{entityResource.Body.ToODataQuery(string.Empty)}"); + new ODataQueryResource($"{_baseUrl}{entityResource.Body.ToODataQuery()}"); } } \ No newline at end of file diff --git a/src/OData.QueryBuilder/Expressions/ExpandExpression.cs b/src/OData.QueryBuilder/Expressions/ExpandExpression.cs index 27a080fd..8a63945f 100644 --- a/src/OData.QueryBuilder/Expressions/ExpandExpression.cs +++ b/src/OData.QueryBuilder/Expressions/ExpandExpression.cs @@ -2,7 +2,7 @@ namespace OData.QueryBuilder.Expressions { - public sealed class ExpandExpression : Expression + public class ExpandExpression : Expression { } } diff --git a/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs index 6881fb96..7f168f2f 100644 --- a/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs @@ -4,7 +4,7 @@ namespace OData.QueryBuilder.Extensions { internal static class ExpressionExtensions { - public static string ToODataQuery(this Expression expression, string queryString) + public static string ToODataQuery(this Expression expression, string queryString = "") { switch (expression) { diff --git a/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs b/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs index b31800d3..b32418d7 100644 --- a/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs +++ b/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs @@ -9,10 +9,8 @@ public interface IODataQueryFunction string Substringof(); - IEnumerable In(IEnumerable enumerable); + bool In(IEnumerable enumerable); - IEnumerable In(IEnumerable enumerable); - - IEnumerable In(IEnumerable enumerable); + bool In(IEnumerable enumerable); } } diff --git a/src/OData.QueryBuilder/Parameters/IODataQueryParameter.cs b/src/OData.QueryBuilder/IODataQuery.cs similarity index 63% rename from src/OData.QueryBuilder/Parameters/IODataQueryParameter.cs rename to src/OData.QueryBuilder/IODataQuery.cs index d0d21c76..ea2608a4 100644 --- a/src/OData.QueryBuilder/Parameters/IODataQueryParameter.cs +++ b/src/OData.QueryBuilder/IODataQuery.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -namespace OData.QueryBuilder.Parameters +namespace OData.QueryBuilder { - public interface IODataQueryParameter + public interface IODataQuery { Uri ToUri(); diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs b/src/OData.QueryBuilder/ODataQuery.cs similarity index 86% rename from src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs rename to src/OData.QueryBuilder/ODataQuery.cs index 7135fc42..6046bcba 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameter.cs +++ b/src/OData.QueryBuilder/ODataQuery.cs @@ -3,14 +3,14 @@ using System.Collections.Generic; using System.Text; -namespace OData.QueryBuilder.Parameters +namespace OData.QueryBuilder { - public class ODataQueryParameter : IODataQueryParameter + public class ODataQuery : IODataQuery { protected readonly StringBuilder _stringBuilder; protected readonly string _resourceName; - public ODataQueryParameter(StringBuilder queryBuilder) + public ODataQuery(StringBuilder queryBuilder) { _stringBuilder = queryBuilder; _resourceName = typeof(TEntity).Name; diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs b/src/OData.QueryBuilder/ODataQueryNested.cs similarity index 60% rename from src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs rename to src/OData.QueryBuilder/ODataQueryNested.cs index 8032c618..796b5ea3 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameterBase.cs +++ b/src/OData.QueryBuilder/ODataQueryNested.cs @@ -1,13 +1,13 @@ using OData.QueryBuilder.Constants; using System.Text; -namespace OData.QueryBuilder.Parameters.Nested +namespace OData.QueryBuilder { - public abstract class ODataQueryNestedParameterBase + public class ODataQueryNested { protected readonly StringBuilder _stringBuilder; - public ODataQueryNestedParameterBase(StringBuilder queryBuilder) => + public ODataQueryNested(StringBuilder queryBuilder) => _stringBuilder = queryBuilder; public string Query => _stringBuilder.ToString().Trim(ODataQuerySeparators.NestedChar); diff --git a/src/OData.QueryBuilder/Parameters/IODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/IODataQueryParameterKey.cs index 1b8fdc5d..e764b894 100644 --- a/src/OData.QueryBuilder/Parameters/IODataQueryParameterKey.cs +++ b/src/OData.QueryBuilder/Parameters/IODataQueryParameterKey.cs @@ -4,7 +4,7 @@ namespace OData.QueryBuilder.Parameters { - public interface IODataQueryParameterKey: IODataQueryParameter + public interface IODataQueryParameterKey : IODataQuery { IODataQueryParameterKey Expand(Expression> entityExpand); diff --git a/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs index 59bb5be5..53b1f21d 100644 --- a/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs @@ -5,7 +5,7 @@ namespace OData.QueryBuilder.Parameters { - public interface IODataQueryParameterList : IODataQueryParameter + public interface IODataQueryParameterList: IODataQuery { IODataQueryParameterList Filter(Expression> entityFilter); diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs index 0630984c..0b2dc700 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs @@ -7,7 +7,7 @@ namespace OData.QueryBuilder.Parameters.Nested { - public class ODataQueryNestedParameter : ODataQueryNestedParameterBase, IODataQueryNestedParameter + public class ODataQueryNestedParameter : ODataQueryNested, IODataQueryNestedParameter { public ODataQueryNestedParameter() : base(new StringBuilder()) @@ -16,7 +16,7 @@ public ODataQueryNestedParameter() public IODataQueryNestedParameter Expand(Expression> entityNestedExpand) { - var query = entityNestedExpand.Body.ToODataQuery(string.Empty); + var query = entityNestedExpand.Body.ToODataQuery(); _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.NestedString}"); @@ -36,7 +36,7 @@ public IODataQueryNestedParameter Expand(Action Filter(Expression> entityNestedFilter) { - var query = entityNestedFilter.Body.ToODataQuery(string.Empty); + var query = entityNestedFilter.Body.ToODataQuery(); _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.NestedString}"); @@ -45,7 +45,7 @@ public IODataQueryNestedParameter Filter(Expression public IODataQueryNestedParameter OrderBy(Expression> entityNestedOrderBy) { - var query = entityNestedOrderBy.Body.ToODataQuery(string.Empty); + var query = entityNestedOrderBy.Body.ToODataQuery(); _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Asc}{ODataQuerySeparators.NestedString}"); @@ -54,7 +54,7 @@ public IODataQueryNestedParameter OrderBy(Expression OrderByDescending(Expression> entityNestedOrderByDescending) { - var query = entityNestedOrderByDescending.Body.ToODataQuery(string.Empty); + var query = entityNestedOrderByDescending.Body.ToODataQuery(); _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Desc}{ODataQuerySeparators.NestedString}"); @@ -63,7 +63,7 @@ public IODataQueryNestedParameter OrderByDescending(Expression Select(Expression> entityNestedSelect) { - var query = entityNestedSelect.Body.ToODataQuery(string.Empty); + var query = entityNestedSelect.Body.ToODataQuery(); _stringBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.NestedString}"); diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs index 164659b5..723273a4 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs @@ -7,7 +7,7 @@ namespace OData.QueryBuilder.Parameters { - public class ODataQueryParameterKey : ODataQueryParameter, IODataQueryParameterKey + public class ODataQueryParameterKey : ODataQuery, IODataQueryParameterKey { public ODataQueryParameterKey(StringBuilder queryBuilder) : base(queryBuilder) @@ -16,7 +16,7 @@ public ODataQueryParameterKey(StringBuilder queryBuilder) public IODataQueryParameterKey Expand(Expression> entityExpand) { - var query = entityExpand.Body.ToODataQuery(string.Empty); + var query = entityExpand.Body.ToODataQuery(); _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); @@ -36,7 +36,7 @@ public IODataQueryParameterKey Expand(Action Select(Expression> entitySelect) { - var query = entitySelect.Body.ToODataQuery(string.Empty); + var query = entitySelect.Body.ToODataQuery(); _stringBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs index 9bb60d4a..7f70a444 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs @@ -8,7 +8,7 @@ namespace OData.QueryBuilder.Parameters { - public class ODataQueryParameterList : ODataQueryParameter, IODataQueryParameterList + public class ODataQueryParameterList : ODataQuery, IODataQueryParameterList { public ODataQueryParameterList(StringBuilder queryBuilder) : base(queryBuilder) @@ -17,7 +17,7 @@ public ODataQueryParameterList(StringBuilder queryBuilder) : public IODataQueryParameterList Filter(Expression> entityFilter) { - var query = entityFilter.Body.ToODataQuery(string.Empty); + var query = entityFilter.Body.ToODataQuery(); _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); @@ -26,7 +26,7 @@ public IODataQueryParameterList Filter(Expression> public IODataQueryParameterList Filter(Expression> entityFilter) { - var query = entityFilter.Body.ToODataQuery(string.Empty); + var query = entityFilter.Body.ToODataQuery(); _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); @@ -35,7 +35,7 @@ public IODataQueryParameterList Filter(Expression Expand(Expression> entityExpand) { - var query = entityExpand.Body.ToODataQuery(string.Empty); + var query = entityExpand.Body.ToODataQuery(); _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); @@ -55,7 +55,7 @@ public IODataQueryParameterList Expand(Action Select(Expression> entitySelect) { - var query = entitySelect.Body.ToODataQuery(string.Empty); + var query = entitySelect.Body.ToODataQuery(); _stringBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); @@ -64,7 +64,7 @@ public IODataQueryParameterList Select(Expression public IODataQueryParameterList OrderBy(Expression> entityOrderBy) { - var query = entityOrderBy.Body.ToODataQuery(string.Empty); + var query = entityOrderBy.Body.ToODataQuery(); _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Asc}{ODataQuerySeparators.MainString}"); @@ -73,7 +73,7 @@ public IODataQueryParameterList OrderBy(Expression OrderByDescending(Expression> entityOrderByDescending) { - var query = entityOrderByDescending.Body.ToODataQuery(string.Empty); + var query = entityOrderByDescending.Body.ToODataQuery(); _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Desc}{ODataQuerySeparators.MainString}"); From 8500ea45cc37b3ff046371e68e4b7f337b19a069 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Mon, 11 May 2020 19:03:16 +0300 Subject: [PATCH 15/76] #ZEX#fix --- src/OData.QueryBuilder/Expressions/ExpandExpression.cs | 8 -------- src/OData.QueryBuilder/Expressions/FilterExpression.cs | 8 -------- .../Expressions/OrderByDescendingExpression.cs | 8 -------- src/OData.QueryBuilder/Expressions/OrderByExpression.cs | 8 -------- src/OData.QueryBuilder/Expressions/SelectExpression.cs | 8 -------- 5 files changed, 40 deletions(-) delete mode 100644 src/OData.QueryBuilder/Expressions/ExpandExpression.cs delete mode 100644 src/OData.QueryBuilder/Expressions/FilterExpression.cs delete mode 100644 src/OData.QueryBuilder/Expressions/OrderByDescendingExpression.cs delete mode 100644 src/OData.QueryBuilder/Expressions/OrderByExpression.cs delete mode 100644 src/OData.QueryBuilder/Expressions/SelectExpression.cs diff --git a/src/OData.QueryBuilder/Expressions/ExpandExpression.cs b/src/OData.QueryBuilder/Expressions/ExpandExpression.cs deleted file mode 100644 index 8a63945f..00000000 --- a/src/OData.QueryBuilder/Expressions/ExpandExpression.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Expressions -{ - public class ExpandExpression : Expression - { - } -} diff --git a/src/OData.QueryBuilder/Expressions/FilterExpression.cs b/src/OData.QueryBuilder/Expressions/FilterExpression.cs deleted file mode 100644 index 5f8cce65..00000000 --- a/src/OData.QueryBuilder/Expressions/FilterExpression.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Expressions -{ - public sealed class FilterExpression : Expression - { - } -} diff --git a/src/OData.QueryBuilder/Expressions/OrderByDescendingExpression.cs b/src/OData.QueryBuilder/Expressions/OrderByDescendingExpression.cs deleted file mode 100644 index 57aa1dcf..00000000 --- a/src/OData.QueryBuilder/Expressions/OrderByDescendingExpression.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Expressions -{ - public sealed class OrderByDescendingExpression : Expression - { - } -} diff --git a/src/OData.QueryBuilder/Expressions/OrderByExpression.cs b/src/OData.QueryBuilder/Expressions/OrderByExpression.cs deleted file mode 100644 index 3cabc7fd..00000000 --- a/src/OData.QueryBuilder/Expressions/OrderByExpression.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Expressions -{ - public sealed class OrderByExpression : Expression - { - } -} diff --git a/src/OData.QueryBuilder/Expressions/SelectExpression.cs b/src/OData.QueryBuilder/Expressions/SelectExpression.cs deleted file mode 100644 index d0fb7dac..00000000 --- a/src/OData.QueryBuilder/Expressions/SelectExpression.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Expressions -{ - public sealed class SelectExpression : Expression - { - } -} From 9ffcc0f1b1830bbed3d20d07134147bd2822a50e Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sun, 31 May 2020 20:09:36 +0300 Subject: [PATCH 16/76] #ZEX#add odata functions & operators --- .../Constants/ODataQueryFunctions.cs | 10 +- .../Constants/ODataQueryOperators.cs | 11 ++ .../Extensions/LambdaExpressionExtensions.cs | 2 +- .../Extensions/MemberExpressionExtensions.cs | 36 ++++-- .../MethodCallExpressionExtensions.cs | 112 ++++-------------- .../Extensions/NewExpressionExtensions.cs | 5 +- .../Functions/IODataQueryDateFunction.cs | 12 ++ .../Functions/IODataQueryFunction.cs | 14 +-- .../Functions/IODataQueryStringFunction.cs | 12 ++ .../Operators/IODataQueryOperator.cs | 14 +++ .../Parameters/IODataQueryParameterList.cs | 5 +- .../Parameters/ODataQueryParameterList.cs | 15 +-- ...yTest.cs => ODataQueryParameterKeyTest.cs} | 24 ++-- ...Test.cs => ODataQueryParameterListTest.cs} | 109 +++++++++-------- 14 files changed, 183 insertions(+), 198 deletions(-) create mode 100644 src/OData.QueryBuilder/Constants/ODataQueryOperators.cs create mode 100644 src/OData.QueryBuilder/Functions/IODataQueryDateFunction.cs create mode 100644 src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs create mode 100644 src/OData.QueryBuilder/Operators/IODataQueryOperator.cs rename test/OData.QueryBuilder.Test/{ODataQueryBuilderByKeyTest.cs => ODataQueryParameterKeyTest.cs} (85%) rename test/OData.QueryBuilder.Test/{ODataQueryBuilderByListTest.cs => ODataQueryParameterListTest.cs} (78%) diff --git a/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs b/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs index 824c15e3..89e8f088 100644 --- a/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs +++ b/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs @@ -2,16 +2,10 @@ { internal struct ODataQueryFunctions { - public const string Any = "any"; - - public const string All = "all"; - public const string Date = "date"; - public const string Substringof = "substringof"; - - public const string Toupper = "toupper"; + public const string SubstringOf = "substringof"; - public const string In = "in"; + public const string ToUpper = "toupper"; } } diff --git a/src/OData.QueryBuilder/Constants/ODataQueryOperators.cs b/src/OData.QueryBuilder/Constants/ODataQueryOperators.cs new file mode 100644 index 00000000..6a956c71 --- /dev/null +++ b/src/OData.QueryBuilder/Constants/ODataQueryOperators.cs @@ -0,0 +1,11 @@ +namespace OData.QueryBuilder.Constants +{ + internal struct ODataQueryOperators + { + public const string Any = "any"; + + public const string All = "all"; + + public const string In = "in"; + } +} diff --git a/src/OData.QueryBuilder/Extensions/LambdaExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/LambdaExpressionExtensions.cs index 9721aaa4..c7092a38 100644 --- a/src/OData.QueryBuilder/Extensions/LambdaExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/LambdaExpressionExtensions.cs @@ -6,7 +6,7 @@ internal static class LambdaExpressionExtensions { public static string ToODataQuery(this LambdaExpression lambdaExpression) { - var filter = lambdaExpression.Body.ToODataQuery(string.Empty); + var filter = lambdaExpression.Body.ToODataQuery(); var tag = lambdaExpression.Parameters[0]?.Name; return $"{tag}:{tag}/{filter}"; diff --git a/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs index 8b11d6ed..e5fd674b 100644 --- a/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs @@ -1,4 +1,6 @@ -using System; +using OData.QueryBuilder.Constants; +using System; +using System.Collections.Generic; using System.Linq.Expressions; namespace OData.QueryBuilder.Extensions @@ -31,6 +33,20 @@ public static string ToODataQuery(this MemberExpression memberExpression, string return $"{dateTimeOffset:s}Z"; } + if (memberExpressionValue is IEnumerable intValues) + { + var intValuesString = string.Join(ODataQuerySeparators.CommaString, intValues); + + return !string.IsNullOrEmpty(intValuesString) ? intValuesString : default; + } + + if (memberExpressionValue is IEnumerable stringValues) + { + var stringValuesString = string.Join($"'{ODataQuerySeparators.CommaString}'", stringValues); + + return !string.IsNullOrEmpty(stringValuesString) ? $"'{stringValuesString}'" : default; + } + return $"{memberExpressionValue}"; } @@ -44,23 +60,21 @@ public static string ToODataQuery(this MemberExpression memberExpression, string return memberExpression.Member.DeclaringType.IsNullableType() ? parentMemberExpressionQuery : - $"{parentMemberExpressionQuery}/{memberExpression.Member.Name}" - ; + $"{parentMemberExpressionQuery}/{memberExpression.Member.Name}"; } public static object GetValue(this MemberExpression memberExpression) { - if (memberExpression.Expression is ConstantExpression ce) + switch (memberExpression.Expression) { - return memberExpression.Member.GetValue(ce.Value); - } + case ConstantExpression ce: + return memberExpression.Member.GetValue(ce.Value); + case MemberExpression me: + return memberExpression.Member.GetValue(GetValue(me)); + default: + return memberExpression.Member.GetValue(); - if (memberExpression.Expression is MemberExpression me) - { - return memberExpression.Member.GetValue(GetValue(me)); } - - return memberExpression.Member.GetValue(); } } } diff --git a/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs index 6ba2b29c..336615c9 100644 --- a/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs @@ -1,7 +1,6 @@ using OData.QueryBuilder.Constants; using OData.QueryBuilder.Functions; -using System.Collections.Generic; -using System.Linq; +using OData.QueryBuilder.Operators; using System.Linq.Expressions; namespace OData.QueryBuilder.Extensions @@ -10,104 +9,41 @@ internal static class MethodCallExpressionExtensions { public static string ToODataQuery(this MethodCallExpression methodCallExpression, string queryString) { - var methodName = methodCallExpression.Method.Name; - var resource = default(object); - var filter = default(string); - - switch (methodName) + switch (methodCallExpression.Method.Name) { - case nameof(IODataQueryFunction.Date): - filter = methodCallExpression.Arguments[0]?.ToODataQuery(queryString) ?? string.Empty; - - return $"{methodName.ToLower()}({filter})"; - - case nameof(Enumerable.All): - case nameof(Enumerable.Any): - resource = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); - filter = methodCallExpression.Arguments[1]?.ToODataQuery(queryString); - - return $"{resource}/{methodName.ToLower()}({filter})"; - - case nameof(Enumerable.Contains): - if (methodCallExpression.Object == default(Expression)) - { - resource = (methodCallExpression.Arguments[0] as MemberExpression).GetValue(); - filter = methodCallExpression.Arguments[1].ToODataQuery(queryString); - } - else if (methodCallExpression.Object is MemberExpression) - { - resource = (methodCallExpression.Object as MemberExpression).GetValue() ?? - methodCallExpression.Object.ToODataQuery(string.Empty); + case nameof(IODataQueryOperator.In): + var resourceIn = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); + var filterIn = methodCallExpression.Arguments[1]?.ToODataQuery(queryString); - filter = methodCallExpression.Arguments[0].ToODataQuery(queryString); - } - else if (methodCallExpression.Object is MethodCallExpression) - { - resource = methodCallExpression.Object.ToODataQuery(string.Empty); - filter = methodCallExpression.Arguments[0].ToODataQuery(string.Empty); - } + return $"{resourceIn} {ODataQueryOperators.In} ({filterIn})"; + case nameof(IODataQueryOperator.All): + var resourceAll = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); + var filterAll = methodCallExpression.Arguments[1]?.ToODataQuery(queryString); - var inSequence = resource.GetInSequence(); + return $"{resourceAll}/{ODataQueryOperators.All}({filterAll})"; + case nameof(IODataQueryOperator.Any): + var resourceAny = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); + var filterAny = methodCallExpression.Arguments[1]?.ToODataQuery(queryString); - if (inSequence != default) - { - if (!string.IsNullOrEmpty(inSequence)) - { - return $"{filter} {inSequence}"; - } - else - { - return $"{ODataQueryFunctions.Substringof}({filter},{resource})"; - } - } + return $"{resourceAny}/{ODataQueryOperators.Any}({filterAny})"; + case nameof(IODataQueryFunction.Date): + var filterDate = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); - return string.Empty; + return $"{ODataQueryFunctions.Date}({filterDate})"; + case nameof(IODataQueryFunction.SubstringOf): + var resourceSof = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); + var filterSof = methodCallExpression.Arguments[1]?.ToODataQuery(queryString); + return $"{ODataQueryFunctions.SubstringOf}({resourceSof},{filterSof})"; case nameof(string.ToUpper): - return $"{ODataQueryFunctions.Toupper}({methodCallExpression.Object.ToODataQuery(string.Empty)})"; + var filterTu = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); + return $"{ODataQueryFunctions.ToUpper}({filterTu})"; case nameof(ToString): - return methodCallExpression.Object.ToODataQuery(string.Empty); - + return methodCallExpression.Object.ToODataQuery(); default: return string.Empty; } } - - private static string GetInSequence(this object arrayObj) - { - if (arrayObj == default) - { - return default; - } - - if (arrayObj is IEnumerable) - { - var inSequenceInt = string.Join(",", arrayObj as IEnumerable); - if (!string.IsNullOrEmpty(inSequenceInt)) - { - return $"{ODataQueryFunctions.In} ({inSequenceInt})"; - } - else - { - return default; - } - } - - if (arrayObj is IEnumerable) - { - var inSequenceInt = string.Join("','", arrayObj as IEnumerable); - if (!string.IsNullOrEmpty(inSequenceInt)) - { - return $"{ODataQueryFunctions.In} ('{inSequenceInt}')"; - } - else - { - return default; - } - } - - return string.Empty; - } } } diff --git a/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs index 0b84485c..947b9585 100644 --- a/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs @@ -1,4 +1,5 @@ -using System; +using OData.QueryBuilder.Constants; +using System; using System.Linq.Expressions; namespace OData.QueryBuilder.Extensions @@ -40,7 +41,7 @@ public static string ToODataQuery(this NewExpression newExpression) names[i] = newExpression.Members[i].Name; } - return string.Join(",", names); + return string.Join(ODataQuerySeparators.CommaString, names); } } } diff --git a/src/OData.QueryBuilder/Functions/IODataQueryDateFunction.cs b/src/OData.QueryBuilder/Functions/IODataQueryDateFunction.cs new file mode 100644 index 00000000..ddb93f03 --- /dev/null +++ b/src/OData.QueryBuilder/Functions/IODataQueryDateFunction.cs @@ -0,0 +1,12 @@ +using System; + +namespace OData.QueryBuilder.Functions +{ + public interface IODataQueryDateFunction + { + /// + /// http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_date + /// + DateTime Date(DateTimeOffset value); + } +} diff --git a/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs b/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs index b32418d7..d503af6d 100644 --- a/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs +++ b/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs @@ -1,16 +1,6 @@ -using System; -using System.Collections.Generic; - -namespace OData.QueryBuilder.Functions +namespace OData.QueryBuilder.Functions { - public interface IODataQueryFunction + public interface IODataQueryFunction : IODataQueryStringFunction, IODataQueryDateFunction { - DateTime Date(DateTimeOffset dateTimeOffset); - - string Substringof(); - - bool In(IEnumerable enumerable); - - bool In(IEnumerable enumerable); } } diff --git a/src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs b/src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs new file mode 100644 index 00000000..12b7228c --- /dev/null +++ b/src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs @@ -0,0 +1,12 @@ +namespace OData.QueryBuilder.Functions +{ + public interface IODataQueryStringFunction + { + bool SubstringOf(string substring, string columnName); + + /// + /// http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_toupper + /// + string ToUpper(string columnName); + } +} diff --git a/src/OData.QueryBuilder/Operators/IODataQueryOperator.cs b/src/OData.QueryBuilder/Operators/IODataQueryOperator.cs new file mode 100644 index 00000000..1f4c09c4 --- /dev/null +++ b/src/OData.QueryBuilder/Operators/IODataQueryOperator.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; + +namespace OData.QueryBuilder.Operators +{ + public interface IODataQueryOperator + { + bool In(T columnName, IEnumerable values); + + bool All(T[] columnName, Func func); + + bool Any(T[] columnName, Func func); + } +} diff --git a/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs index 53b1f21d..6b167011 100644 --- a/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs @@ -1,16 +1,19 @@ using OData.QueryBuilder.Builders.Nested; using OData.QueryBuilder.Functions; +using OData.QueryBuilder.Operators; using System; using System.Linq.Expressions; namespace OData.QueryBuilder.Parameters { - public interface IODataQueryParameterList: IODataQuery + public interface IODataQueryParameterList : IODataQuery { IODataQueryParameterList Filter(Expression> entityFilter); IODataQueryParameterList Filter(Expression> entityFilter); + IODataQueryParameterList Filter(Expression> entityFilter); + IODataQueryParameterList Expand(Expression> entityExpand); IODataQueryParameterList Expand(Action> entityExpandNested); diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs index 7f70a444..b6ec6c86 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs @@ -2,6 +2,7 @@ using OData.QueryBuilder.Constants; using OData.QueryBuilder.Extensions; using OData.QueryBuilder.Functions; +using OData.QueryBuilder.Operators; using System; using System.Linq.Expressions; using System.Text; @@ -18,7 +19,6 @@ public ODataQueryParameterList(StringBuilder queryBuilder) : public IODataQueryParameterList Filter(Expression> entityFilter) { var query = entityFilter.Body.ToODataQuery(); - _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; @@ -27,7 +27,14 @@ public IODataQueryParameterList Filter(Expression> public IODataQueryParameterList Filter(Expression> entityFilter) { var query = entityFilter.Body.ToODataQuery(); + _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); + return this; + } + + public IODataQueryParameterList Filter(Expression> entityFilter) + { + var query = entityFilter.Body.ToODataQuery(); _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; @@ -36,7 +43,6 @@ public IODataQueryParameterList Filter(Expression Expand(Expression> entityExpand) { var query = entityExpand.Body.ToODataQuery(); - _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; @@ -45,9 +51,7 @@ public IODataQueryParameterList Expand(Expression public IODataQueryParameterList Expand(Action> entityExpandNested) { var builder = new ODataQueryNestedBuilder(); - entityExpandNested(builder); - _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{builder.Query}{ODataQuerySeparators.MainString}"); return this; @@ -56,7 +60,6 @@ public IODataQueryParameterList Expand(Action Select(Expression> entitySelect) { var query = entitySelect.Body.ToODataQuery(); - _stringBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; @@ -65,7 +68,6 @@ public IODataQueryParameterList Select(Expression public IODataQueryParameterList OrderBy(Expression> entityOrderBy) { var query = entityOrderBy.Body.ToODataQuery(); - _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Asc}{ODataQuerySeparators.MainString}"); return this; @@ -74,7 +76,6 @@ public IODataQueryParameterList OrderBy(Expression OrderByDescending(Expression> entityOrderByDescending) { var query = entityOrderByDescending.Body.ToODataQuery(); - _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Desc}{ODataQuerySeparators.MainString}"); return this; diff --git a/test/OData.QueryBuilder.Test/ODataQueryBuilderByKeyTest.cs b/test/OData.QueryBuilder.Test/ODataQueryParameterKeyTest.cs similarity index 85% rename from test/OData.QueryBuilder.Test/ODataQueryBuilderByKeyTest.cs rename to test/OData.QueryBuilder.Test/ODataQueryParameterKeyTest.cs index 4fb62ac7..2cbdad7d 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryBuilderByKeyTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryParameterKeyTest.cs @@ -6,14 +6,14 @@ namespace OData.QueryBuilder.Test { - public class ODataQueryBuilderByKeyTest : IClassFixture + public class ODataQueryParameterKeyTest : IClassFixture { private readonly ODataQueryBuilder _odataQueryBuilder; - public ODataQueryBuilderByKeyTest(CommonFixture commonFixture) => + public ODataQueryParameterKeyTest(CommonFixture commonFixture) => _odataQueryBuilder = commonFixture.ODataQueryBuilder1; - [Fact(DisplayName = "(ODataQueryBuilderKey) Expand simple => Success")] + [Fact(DisplayName = "Expand simple => Success")] public void ODataQueryBuilderKey_Expand_Simple_Success() { var uri = _odataQueryBuilder @@ -25,7 +25,7 @@ public void ODataQueryBuilderKey_Expand_Simple_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType(223123123)?$expand=ODataKind"); } - [Fact(DisplayName = "(ODataQueryBuilderKey) Expand simple with key string => Success")] + [Fact(DisplayName = "Expand simple with key string => Success")] public void ODataQueryBuilderKey_Expand_Simple_With_Key_String_Success() { var uri = _odataQueryBuilder @@ -37,7 +37,7 @@ public void ODataQueryBuilderKey_Expand_Simple_With_Key_String_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType('223123123')?$expand=ODataKind"); } - [Fact(DisplayName = "(ODataQueryBuilderKey) Select simple => Success")] + [Fact(DisplayName = "Select simple => Success")] public void ODataQueryBuilderKey_Select_Simple_Success() { var uri = _odataQueryBuilder @@ -49,7 +49,7 @@ public void ODataQueryBuilderKey_Select_Simple_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType(223123123)?$select=IdType"); } - [Fact(DisplayName = "(ODataQueryBuilderKey) Expand and Select => Success")] + [Fact(DisplayName = "Expand and Select => Success")] public void ODataQueryBuilderKey_Expand_Select_Success() { var uri = _odataQueryBuilder @@ -62,7 +62,7 @@ public void ODataQueryBuilderKey_Expand_Select_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType(223123123)?$expand=ODataKind&$select=IdType,Sum"); } - [Fact(DisplayName = "(ODataQueryBuilderKey) Expand nested and Select => Success")] + [Fact(DisplayName = "Expand nested and Select => Success")] public void ODataQueryBuilderKey_ExpandNested_Select_Success() { var uri = _odataQueryBuilder @@ -85,7 +85,7 @@ public void ODataQueryBuilderKey_ExpandNested_Select_Success() } - [Fact(DisplayName = "(ODataQueryBuilderKey) Expand nested orderby => Success")] + [Fact(DisplayName = "Expand nested orderby => Success")] public void ODataQueryBuilderList_ExpandNested_OrderBy_Success() { var uri = _odataQueryBuilder @@ -102,7 +102,7 @@ public void ODataQueryBuilderList_ExpandNested_OrderBy_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType(223123123)?$expand=ODataKindNew($select=IdKind;$orderby=EndDate asc)"); } - [Fact(DisplayName = "(ODataQueryBuilderKey) Expand nested orderby desc => Success")] + [Fact(DisplayName = "Expand nested orderby desc => Success")] public void ODataQueryBuilderList_ExpandNested_OrderByDescending_Success() { var uri = _odataQueryBuilder @@ -119,7 +119,7 @@ public void ODataQueryBuilderList_ExpandNested_OrderByDescending_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType(223123123)?$expand=ODataKindNew($select=IdKind;$orderby=EndDate desc)"); } - [Fact(DisplayName = "(ODataQueryBuilderKey) Expand nested top => Success")] + [Fact(DisplayName = "Expand nested top => Success")] public void ODataQueryBuilderList_ExpandNested_Top_Success() { var uri = _odataQueryBuilder @@ -137,7 +137,7 @@ public void ODataQueryBuilderList_ExpandNested_Top_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType(223123123)?$expand=ODataKindNew($select=IdKind;$orderby=EndDate desc;$top=1)"); } - [Fact(DisplayName = "(ODataQueryBuilderKey) Expand nested Filter => Success")] + [Fact(DisplayName = "Expand nested Filter => Success")] public void ODataQueryBuilderKey_Expand_Nested_Filter_Success() { var uri = _odataQueryBuilder @@ -155,7 +155,7 @@ public void ODataQueryBuilderKey_Expand_Nested_Filter_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType(223123123)?$expand=ODataKind($filter=IdKind eq 1;$select=IdKind)&$select=IdType,Sum"); } - [Fact(DisplayName = "(ODataQueryBuilderKey) ToDicionary => Success")] + [Fact(DisplayName = "ToDicionary => Success")] public void ToDicionaryTest() { var uri = _odataQueryBuilder diff --git a/test/OData.QueryBuilder.Test/ODataQueryBuilderByListTest.cs b/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs similarity index 78% rename from test/OData.QueryBuilder.Test/ODataQueryBuilderByListTest.cs rename to test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs index c71e075e..976ed7fc 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryBuilderByListTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs @@ -1,5 +1,6 @@ using FluentAssertions; using OData.QueryBuilder.Builders; +using OData.QueryBuilder.Parameters; using OData.QueryBuilder.Test.Fakes; using System; using System.Collections.Generic; @@ -8,16 +9,16 @@ namespace OData.QueryBuilder.Test { - public class ODataQueryBuilderByListTest : IClassFixture + public class ODataQueryParameterListTest : IClassFixture { private readonly ODataQueryBuilder _odataQueryBuilder; public static string IdCodeStatic => "testCode"; - public ODataQueryBuilderByListTest(CommonFixture commonFixture) => + public ODataQueryParameterListTest(CommonFixture commonFixture) => _odataQueryBuilder = commonFixture.ODataQueryBuilder2; - [Fact(DisplayName = "(ODataQueryBuilderList) Expand simple => Success")] + [Fact(DisplayName = "Expand simple => Success")] public void ODataQueryBuilderList_Expand_Simple_Success() { var uri = _odataQueryBuilder @@ -29,7 +30,7 @@ public void ODataQueryBuilderList_Expand_Simple_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$expand=ODataKind"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Expand nested => Success")] + [Fact(DisplayName = "Expand nested => Success")] public void ODataQueryBuilderList_ExpandNested_Success() { var uri = _odataQueryBuilder @@ -50,7 +51,7 @@ public void ODataQueryBuilderList_ExpandNested_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$expand=ODataKind($expand=ODataCode($select=IdCode);$select=IdKind),ODataKindNew($select=IdKind),ODataKindNew($select=IdKind)"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Expand nested orderby => Success")] + [Fact(DisplayName = "Expand nested orderby => Success")] public void ODataQueryBuilderList_ExpandNested_OrderBy_Success() { var uri = _odataQueryBuilder @@ -67,7 +68,7 @@ public void ODataQueryBuilderList_ExpandNested_OrderBy_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$expand=ODataKindNew($select=IdKind;$orderby=EndDate asc)"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Expand nested top => Success")] + [Fact(DisplayName = "Expand nested top => Success")] public void ODataQueryBuilderList_ExpandNested_Top_Success() { var uri = _odataQueryBuilder @@ -85,7 +86,7 @@ public void ODataQueryBuilderList_ExpandNested_Top_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$expand=ODataKindNew($select=IdKind;$top=1;$orderby=EndDate asc)"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Expand nested orderby desc => Success")] + [Fact(DisplayName = "Expand nested orderby desc => Success")] public void ODataQueryBuilderList_ExpandNested_OrderByDescending_Success() { var uri = _odataQueryBuilder @@ -102,7 +103,7 @@ public void ODataQueryBuilderList_ExpandNested_OrderByDescending_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$expand=ODataKindNew($select=IdKind;$orderby=EndDate desc)"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Select simple => Success")] + [Fact(DisplayName = "Select simple => Success")] public void ODataQueryBuilderList_Select_Simple_Success() { var uri = _odataQueryBuilder @@ -114,7 +115,7 @@ public void ODataQueryBuilderList_Select_Simple_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$select=IdType"); } - [Fact(DisplayName = "(ODataQueryBuilderList) OrderBy simple => Success")] + [Fact(DisplayName = "OrderBy simple => Success")] public void ODataQueryBuilderList_OrderBy_Simple_Success() { var uri = _odataQueryBuilder @@ -126,7 +127,7 @@ public void ODataQueryBuilderList_OrderBy_Simple_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$orderby=IdType asc"); } - [Fact(DisplayName = "(ODataQueryBuilderList) OrderByDescending simple => Success")] + [Fact(DisplayName = "OrderByDescending simple => Success")] public void ODataQueryBuilderList_OrderByDescending_Simple_Success() { var uri = _odataQueryBuilder @@ -138,7 +139,7 @@ public void ODataQueryBuilderList_OrderByDescending_Simple_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$orderby=IdType desc"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Count simple => Success")] + [Fact(DisplayName = "Count simple => Success")] public void ODataQueryBuilderList_Count_Simple_Success() { var uri = _odataQueryBuilder @@ -150,7 +151,7 @@ public void ODataQueryBuilderList_Count_Simple_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$count=true"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Skip and Top simple => Success")] + [Fact(DisplayName = "Skip and Top simple => Success")] public void ODataQueryBuilderList_Skip_Top_Simple_Success() { var uri = _odataQueryBuilder @@ -163,7 +164,7 @@ public void ODataQueryBuilderList_Skip_Top_Simple_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$skip=1&$top=1"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Filter simple const int=> Success")] + [Fact(DisplayName = "Filter simple const int=> Success")] public void ODataQueryBuilderList_Filter_Simple_Const_Int_Success() { var uri = _odataQueryBuilder @@ -175,7 +176,7 @@ public void ODataQueryBuilderList_Filter_Simple_Const_Int_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=ODataKind/ODataCode/IdCode ge 3 or IdType eq 5"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Filter simple const string => Success")] + [Fact(DisplayName = "Filter simple const string => Success")] public void ODataQueryBuilderList_Filter_Simple_Const_String_Success() { var constValue = "3"; @@ -190,20 +191,20 @@ public void ODataQueryBuilderList_Filter_Simple_Const_String_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=ODataKind/ODataCode/Code eq '3' or ODataKind/ODataCode/Code eq '5' and ODataKind/ODataCode/Code eq 'testCode'"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Filter All/Any => Success")] + [Fact(DisplayName = "Filter All/Any => Success")] public void ODataQueryBuilderList_Filter_All_Any_Success() { var uri = _odataQueryBuilder .For(s => s.ODataType) .ByList() - .Filter(s => s.ODataKind.ODataCodes.Any(v => v.IdCode == 1) - && s.ODataKind.ODataCodes.All(v => v.IdActive)) + .Filter((s, f, o) => o.Any(s.ODataKind.ODataCodes, v => v.IdCode == 1) + && o.All(s.ODataKind.ODataCodes, v => v.IdActive)) .ToUri(); uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=ODataKind/ODataCodes/any(v:v/IdCode eq 1) and ODataKind/ODataCodes/all(v:v/IdActive)"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Expand,Filter,Select,OrderBy,OrderByDescending,Skip,Top,Count => Success")] + [Fact(DisplayName = "Expand,Filter,Select,OrderBy,OrderByDescending,Skip,Top,Count => Success")] public void ODataQueryBuilderList_Expand_Filter_Select_OrderBy_OrderByDescending_Skip_Top_Count_Success() { var constValue = 2; @@ -229,7 +230,7 @@ public void ODataQueryBuilderList_Expand_Filter_Select_OrderBy_OrderByDescending uri.OriginalString.Should().Be($"http://mock/odata/ODataType?$expand=ODataKind&$filter=IdType lt 2 and ODataKind/ODataCode/IdCode ge 3 or IdType eq 5 and IdRule ne null and IdRule eq null&$select=ODataKind,Sum&$orderby=IdType asc&$skip=1&$top=1&$count=true"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Function Date => Success")] + [Fact(DisplayName = "Function Date => Success")] public void ODataQueryBuilderList_Function_Date_Success() { var currentDateToday = new DateTime(2019, 2, 9); @@ -267,7 +268,7 @@ public void ODataQueryBuilderList_Function_Date_Success() $"and date(BeginDate) eq {DateTime.Today:s}Z"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Operator IN => Success")] + [Fact(DisplayName = "Operator IN => Success")] public void ODataQueryBuilderList_Operator_In_Success() { var constStrIds = new[] { "123", "512" }; @@ -280,66 +281,62 @@ public void ODataQueryBuilderList_Operator_In_Success() var uri = _odataQueryBuilder .For(s => s.ODataType) .ByList() - .Filter(s => constStrIds.Contains(s.ODataKind.ODataCode.Code) - && constStrListIds.Contains(s.ODataKind.ODataCode.Code) - && constIntIds.Contains(s.IdType) - && constIntListIds.Contains(s.IdType) - && constIntIds.Contains((int)s.IdRule) - && constIntListIds.Contains((int)s.IdRule) - && newObject.ODataKind.Sequence.Contains(s.ODataKind.IdKind) - && newObjectSequenceArray.ODataKind.SequenceArray.Contains(s.ODataKind.ODataCode.IdCode)) + .Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, constStrIds) + && o.In(s.ODataKind.ODataCode.Code, constStrIds) + && o.In(s.ODataKind.ODataCode.Code, constStrListIds) + && o.In(s.IdType, constIntIds) + && o.In(s.IdType, constIntListIds) + && o.In((int)s.IdRule, constIntIds) + && o.In((int)s.IdRule, constIntListIds) + && o.In(s.ODataKind.IdKind, newObject.ODataKind.Sequence) + && o.In(s.ODataKind.ODataCode.IdCode, newObjectSequenceArray.ODataKind.SequenceArray)) .ToUri(); - uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=ODataKind/ODataCode/Code in ('123','512') and ODataKind/ODataCode/Code in ('123','512') and IdType in (123,512) and IdType in (123,512) and IdRule in (123,512) and IdRule in (123,512) and ODataKind/IdKind in (123,512) and ODataKind/ODataCode/IdCode in (123,512)"); + uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=ODataKind/ODataCode/Code in ('123','512') and ODataKind/ODataCode/Code in ('123','512') and ODataKind/ODataCode/Code in ('123','512') and IdType in (123,512) and IdType in (123,512) and IdRule in (123,512) and IdRule in (123,512) and ODataKind/IdKind in (123,512) and ODataKind/ODataCode/IdCode in (123,512)"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Contains with ToUpper Simple Test => Success")] - public void ODataQueryBuilderList_Test_ContainsSimple() + [Fact(DisplayName = "SubstringOf with ToUpper Simple Test => Success")] + public void ODataQueryBuilderList_Test_Substringof_Simple() { var constValue = "p".ToUpper(); var newObject = new ODataTypeEntity { TypeCode = "TypeCodeValue".ToUpper() }; var uri = _odataQueryBuilder .For(s => s.ODataType) .ByList() - .Filter(s => - s.ODataKind.ODataCode.Code.ToUpper().Contains("W") - || s.ODataKind.ODataCode.Code.Contains(constValue) - || s.ODataKindNew.ODataCode.Code.Contains(newObject.TypeCode) - || s.ODataKindNew.ODataCode.Code.Contains("55")) + .Filter((s, f) => + f.SubstringOf("W", f.ToUpper(s.ODataKind.ODataCode.Code)) + || f.SubstringOf(constValue, s.ODataKind.ODataCode.Code) + || f.SubstringOf(newObject.TypeCode, s.ODataKindNew.ODataCode.Code) + || f.SubstringOf("55", s.ODataKindNew.ODataCode.Code)) .ToUri(); uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=substringof('W',toupper(ODataKind/ODataCode/Code)) or substringof('P',ODataKind/ODataCode/Code) or substringof('TYPECODEVALUE',ODataKindNew/ODataCode/Code) or substringof('55',ODataKindNew/ODataCode/Code)"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Operator IN empty => Success")] + [Fact(DisplayName = "Operator IN empty => Success")] public void ODataQueryBuilderList_Operator_In_Empty_Success() { var constStrIds = default(IEnumerable); var constEmprtyStrListIds = new string[] { }.ToList(); var constIntIds = default(int[]); var constEmptyIntIds = new int[0]; - var constIntListIds = new[] { 123, 512 }.ToList(); - var newObject = new ODataTypeEntity { ODataKind = new ODataKindEntity { Sequence = constIntListIds } }; var newObjectSequenceArray = new ODataTypeEntity { ODataKind = new ODataKindEntity { SequenceArray = constIntIds } }; var uri = _odataQueryBuilder .For(s => s.ODataType) .ByList() - .Filter(s => constStrIds.Contains(s.ODataKind.ODataCode.Code) - && constEmprtyStrListIds.Contains(s.ODataKind.ODataCode.Code) - && constIntIds.Contains(s.IdType) - && constEmptyIntIds.Contains(s.IdType) - && constIntListIds.Contains(s.IdType) - && constIntIds.Contains((int)s.IdRule) - && constIntListIds.Contains((int)s.IdRule) - && newObject.ODataKind.Sequence.Contains(s.ODataKind.IdKind) - && newObjectSequenceArray.ODataKind.SequenceArray.Contains(s.ODataKind.ODataCode.IdCode)) + .Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, constStrIds) + && o.In(s.ODataKind.ODataCode.Code, constEmprtyStrListIds) + && o.In(s.IdType, constIntIds) + && o.In(s.IdType, constEmptyIntIds) + && o.In((int)s.IdRule, constIntIds) + && o.In(s.ODataKind.ODataCode.IdCode, newObjectSequenceArray.ODataKind.SequenceArray)) .ToUri(); uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=IdType in (123,512) and IdRule in (123,512) and ODataKind/IdKind in (123,512)"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Filter boolean values => Success")] + [Fact(DisplayName = "Filter boolean values => Success")] public void ODataQueryBuilderList_Filter_Boolean_Values_Success() { var constValue = false; @@ -357,7 +354,7 @@ public void ODataQueryBuilderList_Filter_Boolean_Values_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=IsActive and IsOpen eq false and IsOpen eq true and ODataKind/ODataCode/IdActive eq false"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Filter brackets => Success")] + [Fact(DisplayName = "Filter brackets => Success")] public void ODataQueryBuilderList_Filter_Brackets_Success() { var constStrIds = new[] { "123", "512" }; @@ -366,17 +363,17 @@ public void ODataQueryBuilderList_Filter_Brackets_Success() var uri = _odataQueryBuilder .For(s => s.ODataType) .ByList() - .Filter((s, f) => s.IdRule == constValue + .Filter((s, f, o) => s.IdRule == constValue && s.IsActive && (f.Date(s.EndDate.Value) == default(DateTimeOffset?) || s.EndDate > DateTime.Today) && (f.Date((DateTimeOffset)s.BeginDate) != default(DateTime?) || f.Date((DateTime)s.BeginDate) <= DateTime.Now) - && constStrIds.Contains(s.ODataKind.ODataCode.Code)) + && o.In(s.ODataKind.ODataCode.Code, constStrIds)) .ToUri(); uri.OriginalString.Should().Be($"http://mock/odata/ODataType?$filter=IdRule eq 3 and IsActive and date(EndDate) eq null or EndDate gt {DateTime.Today:s}Z and date(BeginDate) ne null or date(BeginDate) le {DateTime.Now:s}Z and ODataKind/ODataCode/Code in ('123','512')"); } - [Theory(DisplayName = "(ODataQueryBuilderList) Count value => Success")] + [Theory(DisplayName = "Count value => Success")] [InlineData(true)] [InlineData(false)] public void ODataQueryBuilderList_Count_Value_Success(bool value) @@ -390,7 +387,7 @@ public void ODataQueryBuilderList_Count_Value_Success(bool value) uri.OriginalString.Should().Be($"http://mock/odata/ODataType?$count={value.ToString().ToLower()}"); } - [Fact(DisplayName = "(ODataQueryBuilderList) Filter not bool => Success")] + [Fact(DisplayName = "Filter not bool => Success")] public void ODataQueryBuilderList_Filter_Not__Bool_Success() { var uri = _odataQueryBuilder @@ -402,7 +399,7 @@ public void ODataQueryBuilderList_Filter_Not__Bool_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=IsActive and not IsOpen"); } - [Fact(DisplayName = "(ODataQueryBuilderList) ToDictionary")] + [Fact(DisplayName = "ToDicionary => Success")] public void ToDicionaryTest() { var constValue = false; @@ -429,7 +426,7 @@ public void ToDicionaryTest() dictionary.Should().BeEquivalentTo(resultEquivalent); } - [Fact(DisplayName = "(ODataQueryBuilderList) Filter Enum")] + [Fact(DisplayName = "Filter Enum")] public void FilterEnumTest() { var uri = _odataQueryBuilder From 94144b99e2c2e53f71f28e4c8c6c96a4a7405477 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sun, 31 May 2020 21:06:51 +0300 Subject: [PATCH 17/76] #ZEXSM#use C# latest --- .../ConstantExpressionExtensions.cs | 23 +++---- .../Extensions/ExpressionExtensions.cs | 60 ++++++------------- .../Extensions/ExpressionTypeExtensions.cs | 42 +++++-------- .../Extensions/MemberExpressionExtensions.cs | 18 ++---- .../Extensions/ReflectionExtensions.cs | 13 ++-- .../OData.QueryBuilder.csproj | 1 + 6 files changed, 53 insertions(+), 104 deletions(-) diff --git a/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs index db091e60..dddd55b0 100644 --- a/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs @@ -4,22 +4,15 @@ namespace OData.QueryBuilder.Extensions { internal static class ConstantExpressionExtensions { - public static string ToODataQuery(this ConstantExpression constantExpression) - { - switch (constantExpression.Value) + public static string ToODataQuery(this ConstantExpression constantExpression) => + constantExpression.Value switch { - case bool b: - return b.ToString().ToLower(); - case int i: - return i.ToString(); - case string s: - return $"'{s}'"; - case object o: - return $"'{o}'"; - default: - return "null"; - } - } + bool b => b.ToString().ToLower(), + int i => i.ToString(), + string s => $"'{s}'", + object o => $"'{o}'", + _ => "null", + }; public static object GetValue(this ConstantExpression constantExpression) => constantExpression.Value; diff --git a/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs index 7f168f2f..05fe7d1e 100644 --- a/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs @@ -4,49 +4,25 @@ namespace OData.QueryBuilder.Extensions { internal static class ExpressionExtensions { - public static string ToODataQuery(this Expression expression, string queryString = "") - { - switch (expression) + public static string ToODataQuery(this Expression expression, string queryString = "") => + expression switch { - case BinaryExpression binaryExpression: - return binaryExpression.ToODataQuery(queryString); - - case MemberExpression memberExpression: - return memberExpression.ToODataQuery(queryString); - - case ConstantExpression constantExpression: - return constantExpression.ToODataQuery(); - - case MethodCallExpression methodCallExpression: - return methodCallExpression.ToODataQuery(queryString); - - case NewExpression newExpression: - return newExpression.ToODataQuery(); - - case UnaryExpression unaryExpression: - return unaryExpression.ToODataQuery(queryString); - - case LambdaExpression lambdaExpression: - return lambdaExpression.ToODataQuery(); - - default: - return string.Empty; - } - } - - public static object GetValue(this Expression expression) - { - switch (expression) + BinaryExpression binaryExpression => binaryExpression.ToODataQuery(queryString), + MemberExpression memberExpression => memberExpression.ToODataQuery(queryString), + ConstantExpression constantExpression => constantExpression.ToODataQuery(), + MethodCallExpression methodCallExpression => methodCallExpression.ToODataQuery(queryString), + NewExpression newExpression => newExpression.ToODataQuery(), + UnaryExpression unaryExpression => unaryExpression.ToODataQuery(queryString), + LambdaExpression lambdaExpression => lambdaExpression.ToODataQuery(), + _ => string.Empty, + }; + + public static object GetValue(this Expression expression) => + expression switch { - case MemberExpression memberExpression: - return memberExpression.GetValue(); - - case ConstantExpression constantExpression: - return constantExpression.GetValue(); - - default: - return default; - } - } + MemberExpression memberExpression => memberExpression.GetValue(), + ConstantExpression constantExpression => constantExpression.GetValue(), + _ => default, + }; } } diff --git a/src/OData.QueryBuilder/Extensions/ExpressionTypeExtensions.cs b/src/OData.QueryBuilder/Extensions/ExpressionTypeExtensions.cs index d22d3f85..1535b36d 100644 --- a/src/OData.QueryBuilder/Extensions/ExpressionTypeExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ExpressionTypeExtensions.cs @@ -4,33 +4,21 @@ namespace OData.QueryBuilder.Extensions { internal static class ExpressionTypeExtensions { - public static string ToODataQueryOperator(this ExpressionType expressionType) - { - switch (expressionType) + public static string ToODataQueryOperator(this ExpressionType expressionType) => + expressionType switch { - case ExpressionType.And: - case ExpressionType.AndAlso: - return "and"; - case ExpressionType.Or: - case ExpressionType.OrElse: - return "or"; - case ExpressionType.Equal: - return "eq"; - case ExpressionType.Not: - return "not"; - case ExpressionType.NotEqual: - return "ne"; - case ExpressionType.LessThan: - return "lt"; - case ExpressionType.LessThanOrEqual: - return "le"; - case ExpressionType.GreaterThan: - return "gt"; - case ExpressionType.GreaterThanOrEqual: - return "ge"; - default: - return string.Empty; - } - } + ExpressionType.And => "and", + ExpressionType.AndAlso => "and", + ExpressionType.Or => "or", + ExpressionType.OrElse => "or", + ExpressionType.Equal => "eq", + ExpressionType.Not => "not", + ExpressionType.NotEqual => "ne", + ExpressionType.LessThan => "lt", + ExpressionType.LessThanOrEqual => "le", + ExpressionType.GreaterThan => "gt", + ExpressionType.GreaterThanOrEqual => "ge", + _ => string.Empty, + }; } } diff --git a/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs index e5fd674b..c7bce9fc 100644 --- a/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs @@ -63,18 +63,12 @@ public static string ToODataQuery(this MemberExpression memberExpression, string $"{parentMemberExpressionQuery}/{memberExpression.Member.Name}"; } - public static object GetValue(this MemberExpression memberExpression) - { - switch (memberExpression.Expression) + public static object GetValue(this MemberExpression memberExpression) => + memberExpression.Expression switch { - case ConstantExpression ce: - return memberExpression.Member.GetValue(ce.Value); - case MemberExpression me: - return memberExpression.Member.GetValue(GetValue(me)); - default: - return memberExpression.Member.GetValue(); - - } - } + ConstantExpression ce => memberExpression.Member.GetValue(ce.Value), + MemberExpression me => memberExpression.Member.GetValue(GetValue(me)), + _ => memberExpression.Member.GetValue(), + }; } } diff --git a/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs b/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs index 463d8ef2..83a83771 100644 --- a/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs @@ -9,15 +9,12 @@ public static object GetValue(this MemberInfo memberInfo, object obj = default) { try { - switch (memberInfo) + return memberInfo switch { - case FieldInfo fieldInfo: - return fieldInfo.GetValue(obj); - case PropertyInfo propertyInfo: - return propertyInfo.GetValue(obj, default); - default: - return default; - } + FieldInfo fieldInfo => fieldInfo.GetValue(obj), + PropertyInfo propertyInfo => propertyInfo.GetValue(obj, default), + _ => default, + }; } catch (Exception) { diff --git a/src/OData.QueryBuilder/OData.QueryBuilder.csproj b/src/OData.QueryBuilder/OData.QueryBuilder.csproj index b314705f..d2ea93a8 100644 --- a/src/OData.QueryBuilder/OData.QueryBuilder.csproj +++ b/src/OData.QueryBuilder/OData.QueryBuilder.csproj @@ -4,6 +4,7 @@ netstandard1.3 bin\$(Configuration)\$(TargetFramework)\OData.QueryBuilder.nuspec version=$(PackageVersion) + latest From cabc17650705032de3a222e2fce993a5620186d8 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Tue, 9 Jun 2020 09:59:56 +0300 Subject: [PATCH 18/76] #ZEXSM#rename methods --- .../Extensions/ConstantExpressionExtensions.cs | 2 +- .../Extensions/ExpressionExtensions.cs | 6 +++--- .../Extensions/MemberExpressionExtensions.cs | 12 ++++++------ .../Extensions/NewExpressionExtensions.cs | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs index dddd55b0..a8c52e4f 100644 --- a/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs @@ -14,7 +14,7 @@ public static string ToODataQuery(this ConstantExpression constantExpression) => _ => "null", }; - public static object GetValue(this ConstantExpression constantExpression) => + public static object GetValueOfConstantExpression(this ConstantExpression constantExpression) => constantExpression.Value; } } diff --git a/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs index 05fe7d1e..0a7ab7b0 100644 --- a/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs @@ -17,11 +17,11 @@ public static string ToODataQuery(this Expression expression, string queryString _ => string.Empty, }; - public static object GetValue(this Expression expression) => + public static object GetValueOfExpression(this Expression expression) => expression switch { - MemberExpression memberExpression => memberExpression.GetValue(), - ConstantExpression constantExpression => constantExpression.GetValue(), + MemberExpression memberExpression => memberExpression.GetValueOfMemberExpression(), + ConstantExpression constantExpression => constantExpression.GetValueOfConstantExpression(), _ => default, }; } diff --git a/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs index c7bce9fc..aa23fc80 100644 --- a/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs @@ -9,7 +9,7 @@ internal static class MemberExpressionExtensions { public static string ToODataQuery(this MemberExpression memberExpression, string queryString) { - var memberExpressionValue = memberExpression.GetValue(); + var memberExpressionValue = memberExpression.GetValueOfMemberExpression(); if (memberExpressionValue != default) { @@ -63,12 +63,12 @@ public static string ToODataQuery(this MemberExpression memberExpression, string $"{parentMemberExpressionQuery}/{memberExpression.Member.Name}"; } - public static object GetValue(this MemberExpression memberExpression) => - memberExpression.Expression switch + public static object GetValueOfMemberExpression(this MemberExpression expression) => + expression.Expression switch { - ConstantExpression ce => memberExpression.Member.GetValue(ce.Value), - MemberExpression me => memberExpression.Member.GetValue(GetValue(me)), - _ => memberExpression.Member.GetValue(), + ConstantExpression constantExpression => expression.Member.GetValue(constantExpression.Value), + MemberExpression memberExpression => expression.Member.GetValue(GetValueOfMemberExpression(memberExpression)), + _ => expression.Member.GetValue(), }; } } diff --git a/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs index 947b9585..e654526f 100644 --- a/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs @@ -14,7 +14,7 @@ public static string ToODataQuery(this NewExpression newExpression) for (var i = 0; i < newExpression.Arguments.Count; i++) { - arguments[i] = newExpression.Arguments[i].GetValue(); + arguments[i] = newExpression.Arguments[i].GetValueOfExpression(); } if (newExpression.Type == typeof(DateTime)) From cf0ba5812c3947aed0e11e2a51a6245e0c5e9a2b Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sun, 21 Jun 2020 09:22:49 +0300 Subject: [PATCH 19/76] #ZEX#user visitor --- .../Nested/ODataQueryNestedBuilder.cs | 13 +- .../Builders/ODataQueryBuilder.cs | 10 +- .../Extensions/BinaryExpressionExtensions.cs | 25 --- .../ConstantExpressionExtensions.cs | 20 -- .../Extensions/ExpressionExtensions.cs | 28 --- .../Extensions/LambdaExpressionExtensions.cs | 15 -- .../Extensions/MemberExpressionExtensions.cs | 74 ------- .../MethodCallExpressionExtensions.cs | 49 ----- .../Extensions/NewExpressionExtensions.cs | 47 ----- .../Extensions/ReflectionExtensions.cs | 33 +++- .../Extensions/UnaryExpressionExtensions.cs | 15 -- .../Functions/ICustomFunction.cs | 17 ++ .../Functions/IODataQueryFunction.cs | 2 +- .../OData.QueryBuilder.csproj | 2 +- src/OData.QueryBuilder/ODataQuery.cs | 2 - .../Nested/ODataQueryNestedParameter.cs | 16 +- .../Parameters/ODataQueryParameterKey.cs | 7 +- .../Parameters/ODataQueryParameterList.cs | 30 ++- src/OData.QueryBuilder/Visitor.cs | 182 ++++++++++++++++++ .../ODataQueryParameterListTest.cs | 90 ++++++--- 20 files changed, 353 insertions(+), 324 deletions(-) delete mode 100644 src/OData.QueryBuilder/Extensions/BinaryExpressionExtensions.cs delete mode 100644 src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs delete mode 100644 src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs delete mode 100644 src/OData.QueryBuilder/Extensions/LambdaExpressionExtensions.cs delete mode 100644 src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs delete mode 100644 src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs delete mode 100644 src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs delete mode 100644 src/OData.QueryBuilder/Extensions/UnaryExpressionExtensions.cs create mode 100644 src/OData.QueryBuilder/Functions/ICustomFunction.cs create mode 100644 src/OData.QueryBuilder/Visitor.cs diff --git a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs index 1e5e547c..d55118c3 100644 --- a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs @@ -1,5 +1,4 @@ -using OData.QueryBuilder.Extensions; -using OData.QueryBuilder.Parameters.Nested; +using OData.QueryBuilder.Parameters.Nested; using System; using System.Linq.Expressions; using System.Text; @@ -20,11 +19,17 @@ public IODataQueryNestedParameter For(Expression(); diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index 80c937d7..c64cc295 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -1,5 +1,4 @@ using OData.QueryBuilder.Constants; -using OData.QueryBuilder.Extensions; using OData.QueryBuilder.Resourses; using System; using System.Linq.Expressions; @@ -16,7 +15,12 @@ public ODataQueryBuilder(Uri baseUrl) => public ODataQueryBuilder(string baseUrl) => _baseUrl = $"{baseUrl.TrimEnd(ODataQuerySeparators.SlashChar)}{ODataQuerySeparators.SlashString}"; - public IODataQueryResource For(Expression> entityResource) => - new ODataQueryResource($"{_baseUrl}{entityResource.Body.ToODataQuery()}"); + public IODataQueryResource For(Expression> entityResource) + { + var visitor = new Visitor(entityResource.Body); + var query = visitor.ToString(); + + return new ODataQueryResource($"{_baseUrl}{query}"); + } } } \ No newline at end of file diff --git a/src/OData.QueryBuilder/Extensions/BinaryExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/BinaryExpressionExtensions.cs deleted file mode 100644 index 12b56121..00000000 --- a/src/OData.QueryBuilder/Extensions/BinaryExpressionExtensions.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Extensions -{ - internal static class BinaryExpressionExtensions - { - public static string ToODataQuery(this BinaryExpression binaryExpression, string queryString) - { - var leftQueryString = binaryExpression.Left.ToODataQuery(queryString); - var rightQueryString = binaryExpression.Right.ToODataQuery(queryString); - - if (string.IsNullOrEmpty(leftQueryString)) - { - return rightQueryString; - } - - if (string.IsNullOrEmpty(rightQueryString)) - { - return leftQueryString; - } - - return $"{leftQueryString} {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryString}"; - } - } -} diff --git a/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs deleted file mode 100644 index a8c52e4f..00000000 --- a/src/OData.QueryBuilder/Extensions/ConstantExpressionExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Extensions -{ - internal static class ConstantExpressionExtensions - { - public static string ToODataQuery(this ConstantExpression constantExpression) => - constantExpression.Value switch - { - bool b => b.ToString().ToLower(), - int i => i.ToString(), - string s => $"'{s}'", - object o => $"'{o}'", - _ => "null", - }; - - public static object GetValueOfConstantExpression(this ConstantExpression constantExpression) => - constantExpression.Value; - } -} diff --git a/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs deleted file mode 100644 index 0a7ab7b0..00000000 --- a/src/OData.QueryBuilder/Extensions/ExpressionExtensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Extensions -{ - internal static class ExpressionExtensions - { - public static string ToODataQuery(this Expression expression, string queryString = "") => - expression switch - { - BinaryExpression binaryExpression => binaryExpression.ToODataQuery(queryString), - MemberExpression memberExpression => memberExpression.ToODataQuery(queryString), - ConstantExpression constantExpression => constantExpression.ToODataQuery(), - MethodCallExpression methodCallExpression => methodCallExpression.ToODataQuery(queryString), - NewExpression newExpression => newExpression.ToODataQuery(), - UnaryExpression unaryExpression => unaryExpression.ToODataQuery(queryString), - LambdaExpression lambdaExpression => lambdaExpression.ToODataQuery(), - _ => string.Empty, - }; - - public static object GetValueOfExpression(this Expression expression) => - expression switch - { - MemberExpression memberExpression => memberExpression.GetValueOfMemberExpression(), - ConstantExpression constantExpression => constantExpression.GetValueOfConstantExpression(), - _ => default, - }; - } -} diff --git a/src/OData.QueryBuilder/Extensions/LambdaExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/LambdaExpressionExtensions.cs deleted file mode 100644 index c7092a38..00000000 --- a/src/OData.QueryBuilder/Extensions/LambdaExpressionExtensions.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Extensions -{ - internal static class LambdaExpressionExtensions - { - public static string ToODataQuery(this LambdaExpression lambdaExpression) - { - var filter = lambdaExpression.Body.ToODataQuery(); - var tag = lambdaExpression.Parameters[0]?.Name; - - return $"{tag}:{tag}/{filter}"; - } - } -} diff --git a/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs deleted file mode 100644 index aa23fc80..00000000 --- a/src/OData.QueryBuilder/Extensions/MemberExpressionExtensions.cs +++ /dev/null @@ -1,74 +0,0 @@ -using OData.QueryBuilder.Constants; -using System; -using System.Collections.Generic; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Extensions -{ - internal static class MemberExpressionExtensions - { - public static string ToODataQuery(this MemberExpression memberExpression, string queryString) - { - var memberExpressionValue = memberExpression.GetValueOfMemberExpression(); - - if (memberExpressionValue != default) - { - if (memberExpressionValue is string @string) - { - return $"'{@string}'"; - } - - if (memberExpressionValue is bool @bool) - { - return $"{@bool}".ToLower(); - } - - if (memberExpressionValue is DateTime dateTime) - { - return $"{dateTime:s}Z"; - } - - if (memberExpressionValue is DateTimeOffset dateTimeOffset) - { - return $"{dateTimeOffset:s}Z"; - } - - if (memberExpressionValue is IEnumerable intValues) - { - var intValuesString = string.Join(ODataQuerySeparators.CommaString, intValues); - - return !string.IsNullOrEmpty(intValuesString) ? intValuesString : default; - } - - if (memberExpressionValue is IEnumerable stringValues) - { - var stringValuesString = string.Join($"'{ODataQuerySeparators.CommaString}'", stringValues); - - return !string.IsNullOrEmpty(stringValuesString) ? $"'{stringValuesString}'" : default; - } - - return $"{memberExpressionValue}"; - } - - var parentMemberExpressionQuery = memberExpression.Expression.ToODataQuery(queryString); - - if (string.IsNullOrEmpty(parentMemberExpressionQuery)) - { - return memberExpression.Member.Name; - } - - return memberExpression.Member.DeclaringType.IsNullableType() ? - parentMemberExpressionQuery - : - $"{parentMemberExpressionQuery}/{memberExpression.Member.Name}"; - } - - public static object GetValueOfMemberExpression(this MemberExpression expression) => - expression.Expression switch - { - ConstantExpression constantExpression => expression.Member.GetValue(constantExpression.Value), - MemberExpression memberExpression => expression.Member.GetValue(GetValueOfMemberExpression(memberExpression)), - _ => expression.Member.GetValue(), - }; - } -} diff --git a/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs deleted file mode 100644 index 336615c9..00000000 --- a/src/OData.QueryBuilder/Extensions/MethodCallExpressionExtensions.cs +++ /dev/null @@ -1,49 +0,0 @@ -using OData.QueryBuilder.Constants; -using OData.QueryBuilder.Functions; -using OData.QueryBuilder.Operators; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Extensions -{ - internal static class MethodCallExpressionExtensions - { - public static string ToODataQuery(this MethodCallExpression methodCallExpression, string queryString) - { - switch (methodCallExpression.Method.Name) - { - case nameof(IODataQueryOperator.In): - var resourceIn = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); - var filterIn = methodCallExpression.Arguments[1]?.ToODataQuery(queryString); - - return $"{resourceIn} {ODataQueryOperators.In} ({filterIn})"; - case nameof(IODataQueryOperator.All): - var resourceAll = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); - var filterAll = methodCallExpression.Arguments[1]?.ToODataQuery(queryString); - - return $"{resourceAll}/{ODataQueryOperators.All}({filterAll})"; - case nameof(IODataQueryOperator.Any): - var resourceAny = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); - var filterAny = methodCallExpression.Arguments[1]?.ToODataQuery(queryString); - - return $"{resourceAny}/{ODataQueryOperators.Any}({filterAny})"; - case nameof(IODataQueryFunction.Date): - var filterDate = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); - - return $"{ODataQueryFunctions.Date}({filterDate})"; - case nameof(IODataQueryFunction.SubstringOf): - var resourceSof = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); - var filterSof = methodCallExpression.Arguments[1]?.ToODataQuery(queryString); - - return $"{ODataQueryFunctions.SubstringOf}({resourceSof},{filterSof})"; - case nameof(string.ToUpper): - var filterTu = methodCallExpression.Arguments[0]?.ToODataQuery(queryString); - - return $"{ODataQueryFunctions.ToUpper}({filterTu})"; - case nameof(ToString): - return methodCallExpression.Object.ToODataQuery(); - default: - return string.Empty; - } - } - } -} diff --git a/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs deleted file mode 100644 index e654526f..00000000 --- a/src/OData.QueryBuilder/Extensions/NewExpressionExtensions.cs +++ /dev/null @@ -1,47 +0,0 @@ -using OData.QueryBuilder.Constants; -using System; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Extensions -{ - internal static class NewExpressionExtensions - { - public static string ToODataQuery(this NewExpression newExpression) - { - if (newExpression.Members == default) - { - var arguments = new object[newExpression.Arguments.Count]; - - for (var i = 0; i < newExpression.Arguments.Count; i++) - { - arguments[i] = newExpression.Arguments[i].GetValueOfExpression(); - } - - if (newExpression.Type == typeof(DateTime)) - { - var datetime = newExpression.Constructor.Invoke(arguments); - - return $"{datetime:s}Z"; - } - - if (newExpression.Type == typeof(DateTimeOffset)) - { - var datetime = newExpression.Constructor.Invoke(arguments); - - return $"{datetime:s}Z"; - } - - return string.Empty; - } - - var names = new string[newExpression.Members.Count]; - - for (var i = 0; i < newExpression.Members.Count; i++) - { - names[i] = newExpression.Members[i].Name; - } - - return string.Join(ODataQuerySeparators.CommaString, names); - } - } -} diff --git a/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs b/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs index 83a83771..71b929d4 100644 --- a/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs @@ -1,4 +1,6 @@ -using System; +using OData.QueryBuilder.Constants; +using System; +using System.Collections.Generic; using System.Reflection; namespace OData.QueryBuilder.Extensions @@ -24,5 +26,34 @@ public static object GetValue(this MemberInfo memberInfo, object obj = default) public static bool IsNullableType(this Type type) => Nullable.GetUnderlyingType(type) != default; + + public static string ConvertToString(object @object) + { + switch (@object) + { + case null: + return default; + case string @string: + return $"'{@string}'"; + case bool @bool: + return $"{@bool}".ToLower(); + case int @int: + return $"{@int}"; + case DateTime dateTime: + return $"{dateTime:s}Z"; + case DateTimeOffset dateTimeOffset: + return $"{dateTimeOffset:s}Z"; + case IEnumerable intValues: + var intValuesString = string.Join(ODataQuerySeparators.CommaString, intValues); + + return !string.IsNullOrEmpty(intValuesString) ? intValuesString : default; + case IEnumerable stringValues: + var stringValuesString = string.Join($"'{ODataQuerySeparators.CommaString}'", stringValues); + + return !string.IsNullOrEmpty(stringValuesString) ? $"'{stringValuesString}'" : default; + default: + return $"{@object}"; + } + } } } diff --git a/src/OData.QueryBuilder/Extensions/UnaryExpressionExtensions.cs b/src/OData.QueryBuilder/Extensions/UnaryExpressionExtensions.cs deleted file mode 100644 index 9b404cb3..00000000 --- a/src/OData.QueryBuilder/Extensions/UnaryExpressionExtensions.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Extensions -{ - internal static class UnaryExpressionExtensions - { - public static string ToODataQuery(this UnaryExpression unaryExpression, string queryString) - { - var odataOperator = unaryExpression.NodeType.ToODataQueryOperator(); - odataOperator = !string.IsNullOrEmpty(odataOperator) ? $"{odataOperator} " : string.Empty; - - return $"{odataOperator}{unaryExpression.Operand.ToODataQuery(queryString)}"; - } - } -} diff --git a/src/OData.QueryBuilder/Functions/ICustomFunction.cs b/src/OData.QueryBuilder/Functions/ICustomFunction.cs new file mode 100644 index 00000000..cf54dc58 --- /dev/null +++ b/src/OData.QueryBuilder/Functions/ICustomFunction.cs @@ -0,0 +1,17 @@ +using System; + +namespace OData.QueryBuilder.Functions +{ + public interface ICustomFunction + { + T ConvertEnumToString(T type) where T : Enum; + + DateTime ConvertDateTimeToString(DateTime dateTime, string format); + + DateTime? ConvertDateTimeToString(DateTime? dateTime, string format); + + DateTimeOffset ConvertDateTimeOffsetToString(DateTimeOffset dateTimeOffset, string format); + + DateTimeOffset? ConvertDateTimeOffsetToString(DateTimeOffset? dateTimeOffset, string format); + } +} diff --git a/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs b/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs index d503af6d..357ff866 100644 --- a/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs +++ b/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs @@ -1,6 +1,6 @@ namespace OData.QueryBuilder.Functions { - public interface IODataQueryFunction : IODataQueryStringFunction, IODataQueryDateFunction + public interface IODataQueryFunction : IODataQueryStringFunction, IODataQueryDateFunction, ICustomFunction { } } diff --git a/src/OData.QueryBuilder/OData.QueryBuilder.csproj b/src/OData.QueryBuilder/OData.QueryBuilder.csproj index d2ea93a8..e04f94a7 100644 --- a/src/OData.QueryBuilder/OData.QueryBuilder.csproj +++ b/src/OData.QueryBuilder/OData.QueryBuilder.csproj @@ -1,7 +1,7 @@  true - netstandard1.3 + netstandard2.0 bin\$(Configuration)\$(TargetFramework)\OData.QueryBuilder.nuspec version=$(PackageVersion) latest diff --git a/src/OData.QueryBuilder/ODataQuery.cs b/src/OData.QueryBuilder/ODataQuery.cs index 6046bcba..f33dbe72 100644 --- a/src/OData.QueryBuilder/ODataQuery.cs +++ b/src/OData.QueryBuilder/ODataQuery.cs @@ -8,12 +8,10 @@ namespace OData.QueryBuilder public class ODataQuery : IODataQuery { protected readonly StringBuilder _stringBuilder; - protected readonly string _resourceName; public ODataQuery(StringBuilder queryBuilder) { _stringBuilder = queryBuilder; - _resourceName = typeof(TEntity).Name; } public Dictionary ToDictionary() diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs index 0b2dc700..30938555 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs @@ -1,6 +1,5 @@ using OData.QueryBuilder.Builders.Nested; using OData.QueryBuilder.Constants; -using OData.QueryBuilder.Extensions; using System; using System.Linq.Expressions; using System.Text; @@ -16,7 +15,8 @@ public ODataQueryNestedParameter() public IODataQueryNestedParameter Expand(Expression> entityNestedExpand) { - var query = entityNestedExpand.Body.ToODataQuery(); + var visitor = new Visitor(entityNestedExpand.Body); + var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.NestedString}"); @@ -36,7 +36,8 @@ public IODataQueryNestedParameter Expand(Action Filter(Expression> entityNestedFilter) { - var query = entityNestedFilter.Body.ToODataQuery(); + var visitor = new Visitor(entityNestedFilter.Body); + var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.NestedString}"); @@ -45,7 +46,8 @@ public IODataQueryNestedParameter Filter(Expression public IODataQueryNestedParameter OrderBy(Expression> entityNestedOrderBy) { - var query = entityNestedOrderBy.Body.ToODataQuery(); + var visitor = new Visitor(entityNestedOrderBy.Body); + var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Asc}{ODataQuerySeparators.NestedString}"); @@ -54,7 +56,8 @@ public IODataQueryNestedParameter OrderBy(Expression OrderByDescending(Expression> entityNestedOrderByDescending) { - var query = entityNestedOrderByDescending.Body.ToODataQuery(); + var visitor = new Visitor(entityNestedOrderByDescending.Body); + var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Desc}{ODataQuerySeparators.NestedString}"); @@ -63,7 +66,8 @@ public IODataQueryNestedParameter OrderByDescending(Expression Select(Expression> entityNestedSelect) { - var query = entityNestedSelect.Body.ToODataQuery(); + var visitor = new Visitor(entityNestedSelect.Body); + var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.NestedString}"); diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs index 723273a4..94c3ea70 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs @@ -1,6 +1,5 @@ using OData.QueryBuilder.Builders.Nested; using OData.QueryBuilder.Constants; -using OData.QueryBuilder.Extensions; using System; using System.Linq.Expressions; using System.Text; @@ -16,7 +15,8 @@ public ODataQueryParameterKey(StringBuilder queryBuilder) public IODataQueryParameterKey Expand(Expression> entityExpand) { - var query = entityExpand.Body.ToODataQuery(); + var visitor = new Visitor(entityExpand.Body); + var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); @@ -36,7 +36,8 @@ public IODataQueryParameterKey Expand(Action Select(Expression> entitySelect) { - var query = entitySelect.Body.ToODataQuery(); + var visitor = new Visitor(entitySelect.Body); + var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs index b6ec6c86..f0d1be0e 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs @@ -1,6 +1,5 @@ using OData.QueryBuilder.Builders.Nested; using OData.QueryBuilder.Constants; -using OData.QueryBuilder.Extensions; using OData.QueryBuilder.Functions; using OData.QueryBuilder.Operators; using System; @@ -18,7 +17,9 @@ public ODataQueryParameterList(StringBuilder queryBuilder) : public IODataQueryParameterList Filter(Expression> entityFilter) { - var query = entityFilter.Body.ToODataQuery(); + var visitor = new Visitor(entityFilter.Body); + var query = visitor.ToString(); + _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; @@ -26,7 +27,9 @@ public IODataQueryParameterList Filter(Expression> public IODataQueryParameterList Filter(Expression> entityFilter) { - var query = entityFilter.Body.ToODataQuery(); + var visitor = new Visitor(entityFilter.Body); + var query = visitor.ToString(); + _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; @@ -34,7 +37,9 @@ public IODataQueryParameterList Filter(Expression Filter(Expression> entityFilter) { - var query = entityFilter.Body.ToODataQuery(); + var visitor = new Visitor(entityFilter.Body); + var query = visitor.ToString(); + _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; @@ -42,7 +47,9 @@ public IODataQueryParameterList Filter(Expression Expand(Expression> entityExpand) { - var query = entityExpand.Body.ToODataQuery(); + var visitor = new Visitor(entityExpand.Body); + var query = visitor.ToString(); + _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; @@ -52,6 +59,7 @@ public IODataQueryParameterList Expand(Action(); entityExpandNested(builder); + _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{builder.Query}{ODataQuerySeparators.MainString}"); return this; @@ -59,7 +67,9 @@ public IODataQueryParameterList Expand(Action Select(Expression> entitySelect) { - var query = entitySelect.Body.ToODataQuery(); + var visitor = new Visitor(entitySelect.Body); + var query = visitor.ToString(); + _stringBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); return this; @@ -67,7 +77,9 @@ public IODataQueryParameterList Select(Expression public IODataQueryParameterList OrderBy(Expression> entityOrderBy) { - var query = entityOrderBy.Body.ToODataQuery(); + var visitor = new Visitor(entityOrderBy.Body); + var query = visitor.ToString(); + _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Asc}{ODataQuerySeparators.MainString}"); return this; @@ -75,7 +87,9 @@ public IODataQueryParameterList OrderBy(Expression OrderByDescending(Expression> entityOrderByDescending) { - var query = entityOrderByDescending.Body.ToODataQuery(); + var visitor = new Visitor(entityOrderByDescending.Body); + var query = visitor.ToString(); + _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Desc}{ODataQuerySeparators.MainString}"); return this; diff --git a/src/OData.QueryBuilder/Visitor.cs b/src/OData.QueryBuilder/Visitor.cs new file mode 100644 index 00000000..6be014d4 --- /dev/null +++ b/src/OData.QueryBuilder/Visitor.cs @@ -0,0 +1,182 @@ +using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Extensions; +using OData.QueryBuilder.Functions; +using OData.QueryBuilder.Operators; +using System; +using System.Linq.Expressions; + +namespace OData.QueryBuilder +{ + internal class Visitor + { + private readonly Expression _expression; + + public Visitor(Expression expression) => _expression = expression; + + protected string VisitExpression(Expression expression) => expression switch + { + BinaryExpression binaryExpression => VisitBinaryExpression(binaryExpression), + MemberExpression memberExpression => VisitMemberExpression(memberExpression), + ConstantExpression constantExpression => VisitConstantExpression(constantExpression), + MethodCallExpression methodCallExpression => VisitMethodCallExpression(methodCallExpression), + NewExpression newExpression => VisitNewExpression(newExpression), + UnaryExpression unaryExpression => VisitUnaryExpression(unaryExpression), + LambdaExpression lambdaExpression => VisitLambdaExpression(lambdaExpression), + _ => string.Empty, + }; + + protected string VisitBinaryExpression(BinaryExpression binaryExpression) + { + var leftQueryString = VisitExpression(binaryExpression.Left); + var rightQueryString = VisitExpression(binaryExpression.Right); + + if (string.IsNullOrEmpty(leftQueryString)) + { + return rightQueryString; + } + + if (string.IsNullOrEmpty(rightQueryString)) + { + return leftQueryString; + } + + return $"{leftQueryString} {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryString}"; + } + + protected string VisitMemberExpression(MemberExpression memberExpression) => + IsResourceOfMemberExpression(memberExpression) ? + CreatePath(memberExpression) : ReflectionExtensions.ConvertToString(GetValueOfMemberExpression(memberExpression)); + + protected string VisitConstantExpression(ConstantExpression constantExpression) => + constantExpression.Value == default ? + "null" : ReflectionExtensions.ConvertToString(constantExpression.Value); + + protected string VisitMethodCallExpression(MethodCallExpression methodCallExpression) + { + switch (methodCallExpression.Method.Name) + { + case nameof(IODataQueryOperator.In): + var resourceIn = VisitExpression(methodCallExpression.Arguments[0]); + var filterIn = VisitExpression(methodCallExpression.Arguments[1]) ?? + throw new ArgumentException("Enumeration is empty or null"); + + return $"{resourceIn} {ODataQueryOperators.In} ({filterIn})"; + case nameof(IODataQueryOperator.All): + var resourceAll = VisitExpression(methodCallExpression.Arguments[0]); + var filterAll = VisitExpression(methodCallExpression.Arguments[1]); + + return $"{resourceAll}/{ODataQueryOperators.All}({filterAll})"; + case nameof(IODataQueryOperator.Any): + var resourceAny = VisitExpression(methodCallExpression.Arguments[0]); + var filterAny = VisitExpression(methodCallExpression.Arguments[1]); + + return $"{resourceAny}/{ODataQueryOperators.Any}({filterAny})"; + case nameof(IODataQueryFunction.Date): + var filterDate = VisitExpression(methodCallExpression.Arguments[0]); + + return $"{ODataQueryFunctions.Date}({filterDate})"; + case nameof(IODataQueryFunction.SubstringOf): + var resourceSof = VisitExpression(methodCallExpression.Arguments[0]); + var filterSof = VisitExpression(methodCallExpression.Arguments[1]); + + return $"{ODataQueryFunctions.SubstringOf}({resourceSof},{filterSof})"; + case nameof(string.ToUpper): + var filterTu = VisitExpression(methodCallExpression.Arguments[0]); + + return $"{ODataQueryFunctions.ToUpper}({filterTu})"; + case nameof(ICustomFunction.ConvertEnumToString): + var filterCets = VisitExpression(methodCallExpression.Arguments[0]); + + return $"'{filterCets}'"; + case nameof(ToString): + return VisitExpression(methodCallExpression.Object); + default: + return string.Empty; + } + } + + protected string VisitNewExpression(NewExpression newExpression) + { + if (newExpression.Members == default) + { + var arguments = new object[newExpression.Arguments.Count]; + + for (var i = 0; i < newExpression.Arguments.Count; i++) + { + arguments[i] = GetValueOfExpression(newExpression.Arguments[i]); + } + + if (newExpression.Type == typeof(DateTime) || newExpression.Type == typeof(DateTimeOffset)) + { + return ReflectionExtensions.ConvertToString(newExpression.Constructor.Invoke(arguments)); + } + + return string.Empty; + } + + var names = new string[newExpression.Members.Count]; + + for (var i = 0; i < newExpression.Members.Count; i++) + { + names[i] = newExpression.Members[i].Name; + } + + return string.Join(ODataQuerySeparators.CommaString, names); + } + + protected string VisitUnaryExpression(UnaryExpression unaryExpression) + { + var odataOperator = unaryExpression.NodeType.ToODataQueryOperator(); + odataOperator = !string.IsNullOrEmpty(odataOperator) ? $"{odataOperator} " : string.Empty; + + return $"{odataOperator}{VisitExpression(unaryExpression.Operand)}"; + } + + protected string VisitLambdaExpression(LambdaExpression lambdaExpression) + { + var tag = lambdaExpression.Parameters[0]?.Name; + var filter = VisitExpression(lambdaExpression.Body); + + return $"{tag}:{tag}/{filter}"; + } + + private object GetValueOfExpression(Expression expression) => expression switch + { + MemberExpression memberExpression => GetValueOfMemberExpression(memberExpression), + ConstantExpression constantExpression => GetValueOfConstantExpression(constantExpression), + _ => default, + }; + + private object GetValueOfConstantExpression(ConstantExpression constantExpression) => + constantExpression.Value; + + private object GetValueOfMemberExpression(MemberExpression expression) => expression.Expression switch + { + ConstantExpression constantExpression => expression.Member.GetValue(constantExpression.Value), + MemberExpression memberExpression => expression.Member.GetValue(GetValueOfMemberExpression(memberExpression)), + _ => expression.Member.GetValue(), + }; + + private bool IsResourceOfMemberExpression(MemberExpression memberExpression) => memberExpression.Expression switch + { + ParameterExpression pe => pe.Type.GetProperty(memberExpression.Member.Name, memberExpression.Type) != default, + MemberExpression me => IsResourceOfMemberExpression(me), + _ => false, + }; + + private string CreatePath(MemberExpression memberExpression) + { + var name = VisitExpression(memberExpression.Expression); + + if (string.IsNullOrEmpty(name)) + { + return memberExpression.Member.Name; + } + + return memberExpression.Member.DeclaringType.IsNullableType() ? + name : $"{name}/{memberExpression.Member.Name}"; + } + + public new string ToString() => VisitExpression(_expression); + } +} diff --git a/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs b/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs index 976ed7fc..e712a5c1 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs @@ -1,6 +1,5 @@ using FluentAssertions; using OData.QueryBuilder.Builders; -using OData.QueryBuilder.Parameters; using OData.QueryBuilder.Test.Fakes; using System; using System.Collections.Generic; @@ -191,7 +190,7 @@ public void ODataQueryBuilderList_Filter_Simple_Const_String_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=ODataKind/ODataCode/Code eq '3' or ODataKind/ODataCode/Code eq '5' and ODataKind/ODataCode/Code eq 'testCode'"); } - [Fact(DisplayName = "Filter All/Any => Success")] + [Fact(DisplayName = "Filter operators All/Any => Success")] public void ODataQueryBuilderList_Filter_All_Any_Success() { var uri = _odataQueryBuilder @@ -215,11 +214,10 @@ public void ODataQueryBuilderList_Expand_Filter_Select_OrderBy_OrderByDescending .ByList() .Expand(s => new { s.ODataKind }) .Filter(s => - (s.IdType < constValue && s.ODataKind.ODataCode.IdCode >= 3) + (s.IdType < constValue && 3 <= s.ODataKind.ODataCode.IdCode) || s.IdType == 5 && s.IdRule != default(int?) - && s.IdRule == null - ) + && s.IdRule == null) .Select(s => new { s.ODataKind, s.Sum }) .OrderBy(s => new { s.IdType }) .Skip(1) @@ -227,7 +225,7 @@ public void ODataQueryBuilderList_Expand_Filter_Select_OrderBy_OrderByDescending .Count() .ToUri(); - uri.OriginalString.Should().Be($"http://mock/odata/ODataType?$expand=ODataKind&$filter=IdType lt 2 and ODataKind/ODataCode/IdCode ge 3 or IdType eq 5 and IdRule ne null and IdRule eq null&$select=ODataKind,Sum&$orderby=IdType asc&$skip=1&$top=1&$count=true"); + uri.OriginalString.Should().Be($"http://mock/odata/ODataType?$expand=ODataKind&$filter=IdType lt 2 and 3 le ODataKind/ODataCode/IdCode or IdType eq 5 and IdRule ne null and IdRule eq null&$select=ODataKind,Sum&$orderby=IdType asc&$skip=1&$top=1&$count=true"); } [Fact(DisplayName = "Function Date => Success")] @@ -313,27 +311,75 @@ public void ODataQueryBuilderList_Test_Substringof_Simple() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=substringof('W',toupper(ODataKind/ODataCode/Code)) or substringof('P',ODataKind/ODataCode/Code) or substringof('TYPECODEVALUE',ODataKindNew/ODataCode/Code) or substringof('55',ODataKindNew/ODataCode/Code)"); } - [Fact(DisplayName = "Operator IN empty => Success")] - public void ODataQueryBuilderList_Operator_In_Empty_Success() + [Fact(DisplayName = "Operator IN is null => ArgumentException 1")] + public void ODataQueryBuilderList_Operator_In_is_null_1() { - var constStrIds = default(IEnumerable); var constEmprtyStrListIds = new string[] { }.ToList(); + + _odataQueryBuilder.Invoking( + (r) => r + .For(s => s.ODataType) + .ByList() + .Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, constEmprtyStrListIds)) + .ToUri()) + .Should().Throw().WithMessage("Enumeration is empty or null"); + } + + [Fact(DisplayName = "Operator IN is null => ArgumentException 2")] + public void ODataQueryBuilderList_Operator_In_is_null_2() + { + var constStrIds = default(IEnumerable); + + _odataQueryBuilder.Invoking( + (r) => r + .For(s => s.ODataType) + .ByList() + .Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, constStrIds)) + .ToUri()) + .Should().Throw().WithMessage("Enumeration is empty or null"); + } + + [Fact(DisplayName = "Operator IN is null => ArgumentException 3")] + public void ODataQueryBuilderList_Operator_In_is_null_3() + { + var constIntIds = default(int[]); + + _odataQueryBuilder.Invoking( + (r) => r + .For(s => s.ODataType) + .ByList() + .Filter((s, f, o) => o.In(s.IdType, constIntIds)) + .ToUri()) + .Should().Throw().WithMessage("Enumeration is empty or null"); + } + + [Fact(DisplayName = "Operator IN is null => ArgumentException 4")] + public void ODataQueryBuilderList_Operator_In_is_null_4() + { var constIntIds = default(int[]); - var constEmptyIntIds = new int[0]; var newObjectSequenceArray = new ODataTypeEntity { ODataKind = new ODataKindEntity { SequenceArray = constIntIds } }; - var uri = _odataQueryBuilder - .For(s => s.ODataType) - .ByList() - .Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, constStrIds) - && o.In(s.ODataKind.ODataCode.Code, constEmprtyStrListIds) - && o.In(s.IdType, constIntIds) - && o.In(s.IdType, constEmptyIntIds) - && o.In((int)s.IdRule, constIntIds) - && o.In(s.ODataKind.ODataCode.IdCode, newObjectSequenceArray.ODataKind.SequenceArray)) - .ToUri(); + _odataQueryBuilder.Invoking( + (r) => r + .For(s => s.ODataType) + .ByList() + .Filter((s, f, o) => o.In(s.ODataKind.ODataCode.IdCode, newObjectSequenceArray.ODataKind.SequenceArray)) + .ToUri()) + .Should().Throw().WithMessage("Enumeration is empty or null"); + } + + [Fact(DisplayName = "Operator IN is empty => ArgumentException")] + public void ODataQueryBuilderList_Operator_In_is_empty_1() + { + var constEmptyIntIds = new int[0]; - uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=IdType in (123,512) and IdRule in (123,512) and ODataKind/IdKind in (123,512)"); + _odataQueryBuilder.Invoking( + (r) => r + .For(s => s.ODataType) + .ByList() + .Filter((s, f, o) => o.In(s.IdType, constEmptyIntIds)) + .ToUri()) + .Should().Throw().WithMessage("Enumeration is empty or null"); } [Fact(DisplayName = "Filter boolean values => Success")] @@ -432,7 +478,7 @@ public void FilterEnumTest() var uri = _odataQueryBuilder .For(s => s.ODataType) .ByList() - .Filter(s => s.ODataKind.Color.ToString() == ColorEnum.Blue.ToString() + .Filter((s, f) => s.ODataKind.Color == f.ConvertEnumToString(ColorEnum.Blue) && s.ODataKind.Color == ColorEnum.Blue) .Skip(1) .Top(10) From 989ced75fc75fa33cdc4208c0a9f94f2b31184a3 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sun, 21 Jun 2020 10:05:38 +0300 Subject: [PATCH 20/76] #ZEXSM#review --- src/OData.QueryBuilder/ODataQuery.cs | 6 ++---- src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs | 4 ++-- .../Parameters/ODataQueryParameterList.cs | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/OData.QueryBuilder/ODataQuery.cs b/src/OData.QueryBuilder/ODataQuery.cs index f33dbe72..b1c04623 100644 --- a/src/OData.QueryBuilder/ODataQuery.cs +++ b/src/OData.QueryBuilder/ODataQuery.cs @@ -9,10 +9,8 @@ public class ODataQuery : IODataQuery { protected readonly StringBuilder _stringBuilder; - public ODataQuery(StringBuilder queryBuilder) - { - _stringBuilder = queryBuilder; - } + public ODataQuery(StringBuilder stringBuilder) => + _stringBuilder = stringBuilder; public Dictionary ToDictionary() { diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs index 94c3ea70..9448787f 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs @@ -8,8 +8,8 @@ namespace OData.QueryBuilder.Parameters { public class ODataQueryParameterKey : ODataQuery, IODataQueryParameterKey { - public ODataQueryParameterKey(StringBuilder queryBuilder) - : base(queryBuilder) + public ODataQueryParameterKey(StringBuilder stringBuilder) + : base(stringBuilder) { } diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs index f0d1be0e..dc8ee5f4 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs @@ -10,8 +10,8 @@ namespace OData.QueryBuilder.Parameters { public class ODataQueryParameterList : ODataQuery, IODataQueryParameterList { - public ODataQueryParameterList(StringBuilder queryBuilder) : - base(queryBuilder) + public ODataQueryParameterList(StringBuilder stringBuilder) : + base(stringBuilder) { } From 8fba7fa3e7d948ea2685f148d1ef9fd98d37e0a9 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sun, 21 Jun 2020 19:32:23 +0300 Subject: [PATCH 21/76] #ZEXSM#add convert functions --- ...ICustomFunction.cs => IConvertFunction.cs} | 6 +- .../Functions/IODataQueryFunction.cs | 2 +- src/OData.QueryBuilder/Visitor.cs | 14 ++++- .../ODataQueryParameterListTest.cs | 58 +++++++++++++++++++ 4 files changed, 71 insertions(+), 9 deletions(-) rename src/OData.QueryBuilder/Functions/{ICustomFunction.cs => IConvertFunction.cs} (58%) diff --git a/src/OData.QueryBuilder/Functions/ICustomFunction.cs b/src/OData.QueryBuilder/Functions/IConvertFunction.cs similarity index 58% rename from src/OData.QueryBuilder/Functions/ICustomFunction.cs rename to src/OData.QueryBuilder/Functions/IConvertFunction.cs index cf54dc58..8fd1bea0 100644 --- a/src/OData.QueryBuilder/Functions/ICustomFunction.cs +++ b/src/OData.QueryBuilder/Functions/IConvertFunction.cs @@ -2,16 +2,12 @@ namespace OData.QueryBuilder.Functions { - public interface ICustomFunction + public interface IConvertFunction { T ConvertEnumToString(T type) where T : Enum; DateTime ConvertDateTimeToString(DateTime dateTime, string format); - DateTime? ConvertDateTimeToString(DateTime? dateTime, string format); - DateTimeOffset ConvertDateTimeOffsetToString(DateTimeOffset dateTimeOffset, string format); - - DateTimeOffset? ConvertDateTimeOffsetToString(DateTimeOffset? dateTimeOffset, string format); } } diff --git a/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs b/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs index 357ff866..d99db72c 100644 --- a/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs +++ b/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs @@ -1,6 +1,6 @@ namespace OData.QueryBuilder.Functions { - public interface IODataQueryFunction : IODataQueryStringFunction, IODataQueryDateFunction, ICustomFunction + public interface IODataQueryFunction : IODataQueryStringFunction, IODataQueryDateFunction, IConvertFunction { } } diff --git a/src/OData.QueryBuilder/Visitor.cs b/src/OData.QueryBuilder/Visitor.cs index 6be014d4..9cfb17bd 100644 --- a/src/OData.QueryBuilder/Visitor.cs +++ b/src/OData.QueryBuilder/Visitor.cs @@ -84,10 +84,18 @@ protected string VisitMethodCallExpression(MethodCallExpression methodCallExpres var filterTu = VisitExpression(methodCallExpression.Arguments[0]); return $"{ODataQueryFunctions.ToUpper}({filterTu})"; - case nameof(ICustomFunction.ConvertEnumToString): - var filterCets = VisitExpression(methodCallExpression.Arguments[0]); + case nameof(IConvertFunction.ConvertEnumToString): + var @enum = GetValueOfExpression(methodCallExpression.Arguments[0]); - return $"'{filterCets}'"; + return $"'{@enum}'"; + case nameof(IConvertFunction.ConvertDateTimeToString): + var dateTime = (DateTime)GetValueOfExpression(methodCallExpression.Arguments[0]); + + return dateTime.ToString((string)GetValueOfExpression(methodCallExpression.Arguments[1])); + case nameof(IConvertFunction.ConvertDateTimeOffsetToString): + var dateTimeOffset = (DateTimeOffset)GetValueOfExpression(methodCallExpression.Arguments[0]); + + return dateTimeOffset.ToString((string)GetValueOfExpression(methodCallExpression.Arguments[1])); case nameof(ToString): return VisitExpression(methodCallExpression.Object); default: diff --git a/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs b/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs index e712a5c1..a75f2ace 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs @@ -266,6 +266,64 @@ public void ODataQueryBuilderList_Function_Date_Success() $"and date(BeginDate) eq {DateTime.Today:s}Z"); } + [Fact(DisplayName = "Function Datetime convert => Success")] + public void ODataQueryBuilderList_Function_Datetime_convert_Success() + { + var currentDateToday = new DateTime?(new DateTime(2019, 2, 9)); + + var uri = _odataQueryBuilder + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => + f.Date(s.ODataKind.OpenDate) == f.ConvertDateTimeToString(currentDateToday.Value, "yyyy-MM-dd")) + .ToUri(); + + uri.OriginalString.Should().Be($"http://mock/odata/ODataType?$filter=date(ODataKind/OpenDate) eq 2019-02-09"); + } + + [Fact(DisplayName = "Function Datetime convert => Exception")] + public void ODataQueryBuilderList_Function_Datetime_convert_exception() + { + var currentDateToday = new DateTime?(new DateTime(2019, 2, 9)); + + _odataQueryBuilder.Invoking((q) => q + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => + f.Date(s.ODataKind.OpenDate) == f.ConvertDateTimeToString(currentDateToday.Value, "3")) + .ToUri()) + .Should().Throw(); + } + + [Fact(DisplayName = "Function Datetimeoffset convert => Success")] + public void ODataQueryBuilderList_Function_Datetimeoffset_convert_Success() + { + var currentDateToday = new DateTimeOffset?(new DateTime(2019, 2, 9)); + + var uri = _odataQueryBuilder + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => + f.Date(s.ODataKind.OpenDate) == f.ConvertDateTimeOffsetToString(currentDateToday.Value, "yyyy-MM-dd")) + .ToUri(); + + uri.OriginalString.Should().Be($"http://mock/odata/ODataType?$filter=date(ODataKind/OpenDate) eq 2019-02-09"); + } + + [Fact(DisplayName = "Function Datetimeoffset convert => Exception")] + public void ODataQueryBuilderList_Function_Datetimeoffset_convert_exception() + { + var currentDateToday = new DateTimeOffset?(new DateTime(2019, 2, 9)); + + _odataQueryBuilder.Invoking((q) => q + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => + f.Date(s.ODataKind.OpenDate) == f.ConvertDateTimeOffsetToString(currentDateToday.Value, "3")) + .ToUri()) + .Should().Throw(); + } + [Fact(DisplayName = "Operator IN => Success")] public void ODataQueryBuilderList_Operator_In_Success() { From 7ffeb5d9c7c6ad2e3a19a4be3c493ae60059b30b Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sun, 21 Jun 2020 21:07:28 +0300 Subject: [PATCH 22/76] #ZEXSM#review --- .../Builders/Nested/ODataQueryNestedBuilder.cs | 5 +++-- .../Builders/ODataQueryBuilder.cs | 3 ++- .../Nested/ODataQueryNestedParameter.cs | 11 ++++++----- .../Parameters/ODataQueryParameterKey.cs | 5 +++-- .../Parameters/ODataQueryParameterList.cs | 15 ++++++++------- .../{Visitor.cs => Visitors/VisitorExpression.cs} | 6 +++--- 6 files changed, 25 insertions(+), 20 deletions(-) rename src/OData.QueryBuilder/{Visitor.cs => Visitors/VisitorExpression.cs} (98%) diff --git a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs index d55118c3..ea1da26f 100644 --- a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs @@ -1,4 +1,5 @@ using OData.QueryBuilder.Parameters.Nested; +using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; using System.Text; @@ -19,14 +20,14 @@ public IODataQueryNestedParameter For(Expression public IODataQueryResource For(Expression> entityResource) { - var visitor = new Visitor(entityResource.Body); + var visitor = new VisitorExpression(entityResource.Body); var query = visitor.ToString(); return new ODataQueryResource($"{_baseUrl}{query}"); diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs index 30938555..79828fda 100644 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs +++ b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs @@ -1,5 +1,6 @@ using OData.QueryBuilder.Builders.Nested; using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; using System.Text; @@ -15,7 +16,7 @@ public ODataQueryNestedParameter() public IODataQueryNestedParameter Expand(Expression> entityNestedExpand) { - var visitor = new Visitor(entityNestedExpand.Body); + var visitor = new VisitorExpression(entityNestedExpand.Body); var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.NestedString}"); @@ -36,7 +37,7 @@ public IODataQueryNestedParameter Expand(Action Filter(Expression> entityNestedFilter) { - var visitor = new Visitor(entityNestedFilter.Body); + var visitor = new VisitorExpression(entityNestedFilter.Body); var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.NestedString}"); @@ -46,7 +47,7 @@ public IODataQueryNestedParameter Filter(Expression public IODataQueryNestedParameter OrderBy(Expression> entityNestedOrderBy) { - var visitor = new Visitor(entityNestedOrderBy.Body); + var visitor = new VisitorExpression(entityNestedOrderBy.Body); var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Asc}{ODataQuerySeparators.NestedString}"); @@ -56,7 +57,7 @@ public IODataQueryNestedParameter OrderBy(Expression OrderByDescending(Expression> entityNestedOrderByDescending) { - var visitor = new Visitor(entityNestedOrderByDescending.Body); + var visitor = new VisitorExpression(entityNestedOrderByDescending.Body); var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Desc}{ODataQuerySeparators.NestedString}"); @@ -66,7 +67,7 @@ public IODataQueryNestedParameter OrderByDescending(Expression Select(Expression> entityNestedSelect) { - var visitor = new Visitor(entityNestedSelect.Body); + var visitor = new VisitorExpression(entityNestedSelect.Body); var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.NestedString}"); diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs index 9448787f..71c9320d 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs @@ -1,5 +1,6 @@ using OData.QueryBuilder.Builders.Nested; using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; using System.Text; @@ -15,7 +16,7 @@ public ODataQueryParameterKey(StringBuilder stringBuilder) public IODataQueryParameterKey Expand(Expression> entityExpand) { - var visitor = new Visitor(entityExpand.Body); + var visitor = new VisitorExpression(entityExpand.Body); var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); @@ -36,7 +37,7 @@ public IODataQueryParameterKey Expand(Action Select(Expression> entitySelect) { - var visitor = new Visitor(entitySelect.Body); + var visitor = new VisitorExpression(entitySelect.Body); var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs index dc8ee5f4..0030a181 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs @@ -2,6 +2,7 @@ using OData.QueryBuilder.Constants; using OData.QueryBuilder.Functions; using OData.QueryBuilder.Operators; +using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; using System.Text; @@ -17,7 +18,7 @@ public ODataQueryParameterList(StringBuilder stringBuilder) : public IODataQueryParameterList Filter(Expression> entityFilter) { - var visitor = new Visitor(entityFilter.Body); + var visitor = new VisitorExpression(entityFilter.Body); var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); @@ -27,7 +28,7 @@ public IODataQueryParameterList Filter(Expression> public IODataQueryParameterList Filter(Expression> entityFilter) { - var visitor = new Visitor(entityFilter.Body); + var visitor = new VisitorExpression(entityFilter.Body); var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); @@ -37,7 +38,7 @@ public IODataQueryParameterList Filter(Expression Filter(Expression> entityFilter) { - var visitor = new Visitor(entityFilter.Body); + var visitor = new VisitorExpression(entityFilter.Body); var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); @@ -47,7 +48,7 @@ public IODataQueryParameterList Filter(Expression Expand(Expression> entityExpand) { - var visitor = new Visitor(entityExpand.Body); + var visitor = new VisitorExpression(entityExpand.Body); var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); @@ -67,7 +68,7 @@ public IODataQueryParameterList Expand(Action Select(Expression> entitySelect) { - var visitor = new Visitor(entitySelect.Body); + var visitor = new VisitorExpression(entitySelect.Body); var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); @@ -77,7 +78,7 @@ public IODataQueryParameterList Select(Expression public IODataQueryParameterList OrderBy(Expression> entityOrderBy) { - var visitor = new Visitor(entityOrderBy.Body); + var visitor = new VisitorExpression(entityOrderBy.Body); var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Asc}{ODataQuerySeparators.MainString}"); @@ -87,7 +88,7 @@ public IODataQueryParameterList OrderBy(Expression OrderByDescending(Expression> entityOrderByDescending) { - var visitor = new Visitor(entityOrderByDescending.Body); + var visitor = new VisitorExpression(entityOrderByDescending.Body); var query = visitor.ToString(); _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Desc}{ODataQuerySeparators.MainString}"); diff --git a/src/OData.QueryBuilder/Visitor.cs b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs similarity index 98% rename from src/OData.QueryBuilder/Visitor.cs rename to src/OData.QueryBuilder/Visitors/VisitorExpression.cs index 9cfb17bd..2e2178f8 100644 --- a/src/OData.QueryBuilder/Visitor.cs +++ b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs @@ -5,13 +5,13 @@ using System; using System.Linq.Expressions; -namespace OData.QueryBuilder +namespace OData.QueryBuilder.Visitors { - internal class Visitor + internal class VisitorExpression { private readonly Expression _expression; - public Visitor(Expression expression) => _expression = expression; + public VisitorExpression(Expression expression) => _expression = expression; protected string VisitExpression(Expression expression) => expression switch { From 632b441f4c727984ebb63ca12a7e4ec32ac98bbf Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sun, 21 Jun 2020 21:15:29 +0300 Subject: [PATCH 23/76] #ZEX#review --- src/OData.QueryBuilder/Visitors/VisitorExpression.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs index 2e2178f8..a6ed6f5d 100644 --- a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs +++ b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs @@ -76,18 +76,16 @@ protected string VisitMethodCallExpression(MethodCallExpression methodCallExpres return $"{ODataQueryFunctions.Date}({filterDate})"; case nameof(IODataQueryFunction.SubstringOf): - var resourceSof = VisitExpression(methodCallExpression.Arguments[0]); - var filterSof = VisitExpression(methodCallExpression.Arguments[1]); + var substring = GetValueOfExpression(methodCallExpression.Arguments[0]); + var columName = VisitExpression(methodCallExpression.Arguments[1]); - return $"{ODataQueryFunctions.SubstringOf}({resourceSof},{filterSof})"; - case nameof(string.ToUpper): + return $"{ODataQueryFunctions.SubstringOf}('{substring}',{columName})"; + case nameof(IODataQueryStringFunction.ToUpper): var filterTu = VisitExpression(methodCallExpression.Arguments[0]); return $"{ODataQueryFunctions.ToUpper}({filterTu})"; case nameof(IConvertFunction.ConvertEnumToString): - var @enum = GetValueOfExpression(methodCallExpression.Arguments[0]); - - return $"'{@enum}'"; + return $"'{GetValueOfExpression(methodCallExpression.Arguments[0])}'"; case nameof(IConvertFunction.ConvertDateTimeToString): var dateTime = (DateTime)GetValueOfExpression(methodCallExpression.Arguments[0]); From 1aea7e36cb6b2188ed780806ec59e4478b9363b2 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Mon, 22 Jun 2020 09:55:14 +0300 Subject: [PATCH 24/76] #ZEX#review --- .../Extensions/ExpressionTypeExtensions.cs | 2 +- src/OData.QueryBuilder/Visitors/VisitorExpression.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OData.QueryBuilder/Extensions/ExpressionTypeExtensions.cs b/src/OData.QueryBuilder/Extensions/ExpressionTypeExtensions.cs index 1535b36d..d658bf50 100644 --- a/src/OData.QueryBuilder/Extensions/ExpressionTypeExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ExpressionTypeExtensions.cs @@ -18,7 +18,7 @@ public static string ToODataQueryOperator(this ExpressionType expressionType) => ExpressionType.LessThanOrEqual => "le", ExpressionType.GreaterThan => "gt", ExpressionType.GreaterThanOrEqual => "ge", - _ => string.Empty, + _ => default, }; } } diff --git a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs index a6ed6f5d..dfe24b75 100644 --- a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs +++ b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs @@ -45,7 +45,7 @@ protected string VisitBinaryExpression(BinaryExpression binaryExpression) protected string VisitMemberExpression(MemberExpression memberExpression) => IsResourceOfMemberExpression(memberExpression) ? - CreatePath(memberExpression) : ReflectionExtensions.ConvertToString(GetValueOfMemberExpression(memberExpression)); + CreateResourcePath(memberExpression) : ReflectionExtensions.ConvertToString(GetValueOfMemberExpression(memberExpression)); protected string VisitConstantExpression(ConstantExpression constantExpression) => constantExpression.Value == default ? @@ -133,9 +133,9 @@ protected string VisitNewExpression(NewExpression newExpression) protected string VisitUnaryExpression(UnaryExpression unaryExpression) { var odataOperator = unaryExpression.NodeType.ToODataQueryOperator(); - odataOperator = !string.IsNullOrEmpty(odataOperator) ? $"{odataOperator} " : string.Empty; + var whitespace = odataOperator != default ? " " : string.Empty; - return $"{odataOperator}{VisitExpression(unaryExpression.Operand)}"; + return $"{odataOperator}{whitespace}{VisitExpression(unaryExpression.Operand)}"; } protected string VisitLambdaExpression(LambdaExpression lambdaExpression) @@ -170,7 +170,7 @@ private object GetValueOfConstantExpression(ConstantExpression constantExpressio _ => false, }; - private string CreatePath(MemberExpression memberExpression) + private string CreateResourcePath(MemberExpression memberExpression) { var name = VisitExpression(memberExpression.Expression); From 69d41a47f29b27a6fad62ab3a4f640a9373849c9 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Mon, 22 Jun 2020 10:03:29 +0300 Subject: [PATCH 25/76] #ZEXSM#review --- .../Visitors/VisitorExpression.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs index dfe24b75..aa36c975 100644 --- a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs +++ b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs @@ -22,25 +22,25 @@ internal class VisitorExpression NewExpression newExpression => VisitNewExpression(newExpression), UnaryExpression unaryExpression => VisitUnaryExpression(unaryExpression), LambdaExpression lambdaExpression => VisitLambdaExpression(lambdaExpression), - _ => string.Empty, + _ => default, }; protected string VisitBinaryExpression(BinaryExpression binaryExpression) { - var leftQueryString = VisitExpression(binaryExpression.Left); - var rightQueryString = VisitExpression(binaryExpression.Right); + var left = VisitExpression(binaryExpression.Left); + var right = VisitExpression(binaryExpression.Right); - if (string.IsNullOrEmpty(leftQueryString)) + if (string.IsNullOrEmpty(left)) { - return rightQueryString; + return right; } - if (string.IsNullOrEmpty(rightQueryString)) + if (string.IsNullOrEmpty(right)) { - return leftQueryString; + return left; } - return $"{leftQueryString} {binaryExpression.NodeType.ToODataQueryOperator()} {rightQueryString}"; + return $"{left} {binaryExpression.NodeType.ToODataQueryOperator()} {right}"; } protected string VisitMemberExpression(MemberExpression memberExpression) => @@ -97,7 +97,7 @@ protected string VisitMethodCallExpression(MethodCallExpression methodCallExpres case nameof(ToString): return VisitExpression(methodCallExpression.Object); default: - return string.Empty; + return default; } } @@ -117,7 +117,7 @@ protected string VisitNewExpression(NewExpression newExpression) return ReflectionExtensions.ConvertToString(newExpression.Constructor.Invoke(arguments)); } - return string.Empty; + return default; } var names = new string[newExpression.Members.Count]; @@ -133,7 +133,7 @@ protected string VisitNewExpression(NewExpression newExpression) protected string VisitUnaryExpression(UnaryExpression unaryExpression) { var odataOperator = unaryExpression.NodeType.ToODataQueryOperator(); - var whitespace = odataOperator != default ? " " : string.Empty; + var whitespace = odataOperator != default ? " " : default; return $"{odataOperator}{whitespace}{VisitExpression(unaryExpression.Operand)}"; } From ebed255332755358c16a64450608358f04d74de5 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Mon, 22 Jun 2020 21:29:33 +0300 Subject: [PATCH 26/76] #ZEX#add new functions --- .../Builders/ODataQueryBuilder.cs | 13 ++++-- .../Constants/ODataQueryFunctions.cs | 4 ++ .../Functions/IODataQueryStringFunction.cs | 12 +++++- .../OData.QueryBuilder.csproj | 5 +++ src/OData.QueryBuilder/ODataVersion.cs | 9 ++++ .../Parameters/ODataQueryParameterList.cs | 4 +- .../Resourses/ODataQueryResource.cs | 6 ++- .../Visitors/VisitorExpression.cs | 41 +++++++++++-------- .../ODataQueryParameterListTest.cs | 18 ++++++++ 9 files changed, 89 insertions(+), 23 deletions(-) create mode 100644 src/OData.QueryBuilder/ODataVersion.cs diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index b30de93c..cf96106e 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -9,19 +9,26 @@ namespace OData.QueryBuilder.Builders public class ODataQueryBuilder : IODataQueryBuilder { private readonly string _baseUrl; + private readonly ODataVersion _odataVersion; - public ODataQueryBuilder(Uri baseUrl) => + public ODataQueryBuilder(Uri baseUrl, ODataVersion odataVersion = ODataVersion.V4) + { _baseUrl = $"{baseUrl.OriginalString.TrimEnd(ODataQuerySeparators.SlashChar)}{ODataQuerySeparators.SlashString}"; + _odataVersion = odataVersion; + } - public ODataQueryBuilder(string baseUrl) => + public ODataQueryBuilder(string baseUrl, ODataVersion odataVersion = ODataVersion.V4) + { _baseUrl = $"{baseUrl.TrimEnd(ODataQuerySeparators.SlashChar)}{ODataQuerySeparators.SlashString}"; + _odataVersion = odataVersion; + } public IODataQueryResource For(Expression> entityResource) { var visitor = new VisitorExpression(entityResource.Body); var query = visitor.ToString(); - return new ODataQueryResource($"{_baseUrl}{query}"); + return new ODataQueryResource($"{_baseUrl}{query}", _odataVersion); } } } \ No newline at end of file diff --git a/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs b/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs index 89e8f088..074fcf87 100644 --- a/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs +++ b/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs @@ -6,6 +6,10 @@ internal struct ODataQueryFunctions public const string SubstringOf = "substringof"; + public const string Contains = "contains"; + public const string ToUpper = "toupper"; + + public const string ToLower = "tolower"; } } diff --git a/src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs b/src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs index 12b7228c..f7105073 100644 --- a/src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs +++ b/src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs @@ -2,11 +2,21 @@ { public interface IODataQueryStringFunction { - bool SubstringOf(string substring, string columnName); + bool SubstringOf(string value, string columnName); + + /// + /// http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_contains + /// + bool Contains(string columnName, string value); /// /// http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_toupper /// string ToUpper(string columnName); + + /// + /// http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_tolower + /// + string ToLower(string columnName); } } diff --git a/src/OData.QueryBuilder/OData.QueryBuilder.csproj b/src/OData.QueryBuilder/OData.QueryBuilder.csproj index e04f94a7..35593d92 100644 --- a/src/OData.QueryBuilder/OData.QueryBuilder.csproj +++ b/src/OData.QueryBuilder/OData.QueryBuilder.csproj @@ -14,4 +14,9 @@ Always + + + + + diff --git a/src/OData.QueryBuilder/ODataVersion.cs b/src/OData.QueryBuilder/ODataVersion.cs new file mode 100644 index 00000000..cdb84e8c --- /dev/null +++ b/src/OData.QueryBuilder/ODataVersion.cs @@ -0,0 +1,9 @@ +namespace OData.QueryBuilder +{ + public enum ODataVersion + { + V2, + V3, + V4 + } +} diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs index 0030a181..936b2227 100644 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs +++ b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs @@ -11,8 +11,8 @@ namespace OData.QueryBuilder.Parameters { public class ODataQueryParameterList : ODataQuery, IODataQueryParameterList { - public ODataQueryParameterList(StringBuilder stringBuilder) : - base(stringBuilder) + public ODataQueryParameterList(StringBuilder stringBuilder) + : base(stringBuilder) { } diff --git a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs b/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs index f78f99f8..28a6409e 100644 --- a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs +++ b/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs @@ -7,9 +7,13 @@ namespace OData.QueryBuilder.Resourses public class ODataQueryResource : IODataQueryResource { private readonly StringBuilder _stringBuilder; + private readonly ODataVersion _odataVersion; - public ODataQueryResource(string resourceUrl) => + public ODataQueryResource(string resourceUrl, ODataVersion odataVersion) + { _stringBuilder = new StringBuilder(resourceUrl); + _odataVersion = odataVersion; + } public IODataQueryParameterKey ByKey(int key) { diff --git a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs index aa36c975..0f674330 100644 --- a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs +++ b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs @@ -56,34 +56,43 @@ protected string VisitMethodCallExpression(MethodCallExpression methodCallExpres switch (methodCallExpression.Method.Name) { case nameof(IODataQueryOperator.In): - var resourceIn = VisitExpression(methodCallExpression.Arguments[0]); - var filterIn = VisitExpression(methodCallExpression.Arguments[1]) ?? + var in0 = VisitExpression(methodCallExpression.Arguments[0]); + var in1 = VisitExpression(methodCallExpression.Arguments[1]) ?? throw new ArgumentException("Enumeration is empty or null"); - return $"{resourceIn} {ODataQueryOperators.In} ({filterIn})"; + return $"{in0} {ODataQueryOperators.In} ({in1})"; case nameof(IODataQueryOperator.All): - var resourceAll = VisitExpression(methodCallExpression.Arguments[0]); - var filterAll = VisitExpression(methodCallExpression.Arguments[1]); + var all0 = VisitExpression(methodCallExpression.Arguments[0]); + var all1 = VisitExpression(methodCallExpression.Arguments[1]); - return $"{resourceAll}/{ODataQueryOperators.All}({filterAll})"; + return $"{all0}/{ODataQueryOperators.All}({all1})"; case nameof(IODataQueryOperator.Any): - var resourceAny = VisitExpression(methodCallExpression.Arguments[0]); - var filterAny = VisitExpression(methodCallExpression.Arguments[1]); + var any0 = VisitExpression(methodCallExpression.Arguments[0]); + var any1 = VisitExpression(methodCallExpression.Arguments[1]); - return $"{resourceAny}/{ODataQueryOperators.Any}({filterAny})"; + return $"{any0}/{ODataQueryOperators.Any}({any1})"; case nameof(IODataQueryFunction.Date): - var filterDate = VisitExpression(methodCallExpression.Arguments[0]); + var date0 = VisitExpression(methodCallExpression.Arguments[0]); - return $"{ODataQueryFunctions.Date}({filterDate})"; + return $"{ODataQueryFunctions.Date}({date0})"; case nameof(IODataQueryFunction.SubstringOf): - var substring = GetValueOfExpression(methodCallExpression.Arguments[0]); - var columName = VisitExpression(methodCallExpression.Arguments[1]); + var substringOf0 = GetValueOfExpression(methodCallExpression.Arguments[0]); + var substringOf1 = VisitExpression(methodCallExpression.Arguments[1]); - return $"{ODataQueryFunctions.SubstringOf}('{substring}',{columName})"; + return $"{ODataQueryFunctions.SubstringOf}('{substringOf0}',{substringOf1})"; + case nameof(IODataQueryFunction.Contains): + var contains0 = VisitExpression(methodCallExpression.Arguments[0]); + var contains1 = GetValueOfExpression(methodCallExpression.Arguments[1]); + + return $"{ODataQueryFunctions.Contains}({contains0},'{contains1}')"; case nameof(IODataQueryStringFunction.ToUpper): - var filterTu = VisitExpression(methodCallExpression.Arguments[0]); + var toUpper0 = VisitExpression(methodCallExpression.Arguments[0]); + + return $"{ODataQueryFunctions.ToUpper}({toUpper0})"; + case nameof(IODataQueryStringFunction.ToLower): + var toLower0 = VisitExpression(methodCallExpression.Arguments[0]); - return $"{ODataQueryFunctions.ToUpper}({filterTu})"; + return $"{ODataQueryFunctions.ToLower}({toLower0})"; case nameof(IConvertFunction.ConvertEnumToString): return $"'{GetValueOfExpression(methodCallExpression.Arguments[0])}'"; case nameof(IConvertFunction.ConvertDateTimeToString): diff --git a/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs b/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs index a75f2ace..f7ba48e4 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs @@ -369,6 +369,24 @@ public void ODataQueryBuilderList_Test_Substringof_Simple() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=substringof('W',toupper(ODataKind/ODataCode/Code)) or substringof('P',ODataKind/ODataCode/Code) or substringof('TYPECODEVALUE',ODataKindNew/ODataCode/Code) or substringof('55',ODataKindNew/ODataCode/Code)"); } + [Fact(DisplayName = "Contains with ToLower Simple Test => Success")] + public void ODataQueryBuilderList_Test_Contains_Simple() + { + var constValue = "p".ToLower(); + var newObject = new ODataTypeEntity { TypeCode = "TypeCodeValue".ToLower() }; + var uri = _odataQueryBuilder + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => + f.Contains(f.ToLower(s.ODataKind.ODataCode.Code), "W") + || f.Contains(s.ODataKind.ODataCode.Code, constValue) + || f.Contains(s.ODataKindNew.ODataCode.Code, newObject.TypeCode) + || f.Contains(s.ODataKindNew.ODataCode.Code, "55")) + .ToUri(); + + uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=contains(tolower(ODataKind/ODataCode/Code),'W') or contains(ODataKind/ODataCode/Code,'p') or contains(ODataKindNew/ODataCode/Code,'typecodevalue') or contains(ODataKindNew/ODataCode/Code,'55')"); + } + [Fact(DisplayName = "Operator IN is null => ArgumentException 1")] public void ODataQueryBuilderList_Operator_In_is_null_1() { From 5a19dc6cb1bd36105ac6b1af0f107eef6f391332 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Mon, 22 Jun 2020 21:51:19 +0300 Subject: [PATCH 27/76] #ZEX#restruct proj --- .../Nested/IODataQueryNestedBuilder.cs | 4 +- .../Nested/ODataQueryNestedBuilder.cs | 8 +- .../Builders/ODataQueryBuilder.cs | 4 +- .../QuerySeparators.cs} | 2 +- .../QuerySorts.cs} | 2 +- .../Extensions/ReflectionExtensions.cs | 4 +- .../OData.QueryBuilder.csproj | 5 - src/OData.QueryBuilder/ODataQuery.cs | 6 +- src/OData.QueryBuilder/ODataQueryNested.cs | 2 +- .../Parameters/IODataQueryParameterKey.cs | 15 --- .../Parameters/IODataQueryParameterList.cs | 33 ----- .../Nested/IODataQueryNestedParameter.cs | 23 ---- .../Nested/ODataQueryNestedParameter.cs | 85 ------------ .../Parameters/ODataQueryParameterKey.cs | 48 ------- .../Parameters/ODataQueryParameterList.cs | 120 ----------------- .../Resourses/IODataQueryResource.cs | 8 +- .../Resourses/ODataQueryResource.cs | 20 +-- .../{ => V4}/Constants/ODataQueryFunctions.cs | 2 +- .../{ => V4}/Constants/ODataQueryOperators.cs | 2 +- .../Constants/ODataQueryOptions.cs} | 4 +- .../{ => V4}/Functions/IConvertFunction.cs | 2 +- .../Functions/IODataQueryDateFunction.cs | 2 +- .../{ => V4}/Functions/IODataQueryFunction.cs | 2 +- .../Functions/IODataQueryStringFunction.cs | 2 +- .../{ => V4}/Operators/IODataQueryOperator.cs | 2 +- .../V4/Options/IODataQueryOptionKey.cs | 15 +++ .../V4/Options/IODataQueryOptionList.cs | 33 +++++ .../Options/Nested/IODataQueryOptionNested.cs | 23 ++++ .../Options/Nested/ODataQueryOptionNested.cs | 86 +++++++++++++ .../V4/Options/ODataQueryOptionKey.cs | 49 +++++++ .../V4/Options/ODataQueryOptionList.cs | 121 ++++++++++++++++++ .../Visitors/VisitorExpression.cs | 7 +- ...rKeyTest.cs => ODataQueryOptionKeyTest.cs} | 4 +- ...istTest.cs => ODataQueryOptionListTest.cs} | 4 +- 34 files changed, 374 insertions(+), 375 deletions(-) rename src/OData.QueryBuilder/{Constants/ODataQuerySeparators.cs => Contants/QuerySeparators.cs} (93%) rename src/OData.QueryBuilder/{Constants/ODataQuerySorts.cs => Contants/QuerySorts.cs} (79%) delete mode 100644 src/OData.QueryBuilder/Parameters/IODataQueryParameterKey.cs delete mode 100644 src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs delete mode 100644 src/OData.QueryBuilder/Parameters/Nested/IODataQueryNestedParameter.cs delete mode 100644 src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs delete mode 100644 src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs delete mode 100644 src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs rename src/OData.QueryBuilder/{ => V4}/Constants/ODataQueryFunctions.cs (87%) rename src/OData.QueryBuilder/{ => V4}/Constants/ODataQueryOperators.cs (79%) rename src/OData.QueryBuilder/{Constants/ODataQueryParameters.cs => V4/Constants/ODataQueryOptions.cs} (80%) rename src/OData.QueryBuilder/{ => V4}/Functions/IConvertFunction.cs (87%) rename src/OData.QueryBuilder/{ => V4}/Functions/IODataQueryDateFunction.cs (86%) rename src/OData.QueryBuilder/{ => V4}/Functions/IODataQueryFunction.cs (73%) rename src/OData.QueryBuilder/{ => V4}/Functions/IODataQueryStringFunction.cs (94%) rename src/OData.QueryBuilder/{ => V4}/Operators/IODataQueryOperator.cs (87%) create mode 100644 src/OData.QueryBuilder/V4/Options/IODataQueryOptionKey.cs create mode 100644 src/OData.QueryBuilder/V4/Options/IODataQueryOptionList.cs create mode 100644 src/OData.QueryBuilder/V4/Options/Nested/IODataQueryOptionNested.cs create mode 100644 src/OData.QueryBuilder/V4/Options/Nested/ODataQueryOptionNested.cs create mode 100644 src/OData.QueryBuilder/V4/Options/ODataQueryOptionKey.cs create mode 100644 src/OData.QueryBuilder/V4/Options/ODataQueryOptionList.cs rename test/OData.QueryBuilder.Test/{ODataQueryParameterKeyTest.cs => ODataQueryOptionKeyTest.cs} (97%) rename test/OData.QueryBuilder.Test/{ODataQueryParameterListTest.cs => ODataQueryOptionListTest.cs} (99%) diff --git a/src/OData.QueryBuilder/Builders/Nested/IODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/Nested/IODataQueryNestedBuilder.cs index d4095f8a..0bb400cd 100644 --- a/src/OData.QueryBuilder/Builders/Nested/IODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/Nested/IODataQueryNestedBuilder.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.Parameters.Nested; +using OData.QueryBuilder.V4.Options.Nested; using System; using System.Linq.Expressions; @@ -6,6 +6,6 @@ namespace OData.QueryBuilder.Builders.Nested { public interface IODataQueryNestedBuilder { - IODataQueryNestedParameter For(Expression> nestedEntityExpand); + IODataQueryOptionNested For(Expression> nestedEntityExpand); } } diff --git a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs index ea1da26f..f9958413 100644 --- a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.Parameters.Nested; +using OData.QueryBuilder.V4.Options.Nested; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; @@ -16,7 +16,7 @@ public ODataQueryNestedBuilder() => public string Query => $"{_stringBuilder}({_odataQueryNested.Query})"; - public IODataQueryNestedParameter For(Expression> nestedEntityExpand) + public IODataQueryOptionNested For(Expression> nestedEntityExpand) { if (!string.IsNullOrEmpty(_odataQueryNested?.Query)) { @@ -33,9 +33,9 @@ public IODataQueryNestedParameter For(Expression(); + _odataQueryNested = new ODataQueryOptionNested(); - return _odataQueryNested as ODataQueryNestedParameter; + return _odataQueryNested as ODataQueryOptionNested; } } } diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index cf96106e..67842770 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -13,13 +13,13 @@ public class ODataQueryBuilder : IODataQueryBuilder public ODataQueryBuilder(Uri baseUrl, ODataVersion odataVersion = ODataVersion.V4) { - _baseUrl = $"{baseUrl.OriginalString.TrimEnd(ODataQuerySeparators.SlashChar)}{ODataQuerySeparators.SlashString}"; + _baseUrl = $"{baseUrl.OriginalString.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"; _odataVersion = odataVersion; } public ODataQueryBuilder(string baseUrl, ODataVersion odataVersion = ODataVersion.V4) { - _baseUrl = $"{baseUrl.TrimEnd(ODataQuerySeparators.SlashChar)}{ODataQuerySeparators.SlashString}"; + _baseUrl = $"{baseUrl.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"; _odataVersion = odataVersion; } diff --git a/src/OData.QueryBuilder/Constants/ODataQuerySeparators.cs b/src/OData.QueryBuilder/Contants/QuerySeparators.cs similarity index 93% rename from src/OData.QueryBuilder/Constants/ODataQuerySeparators.cs rename to src/OData.QueryBuilder/Contants/QuerySeparators.cs index 0fb6f856..f2d30894 100644 --- a/src/OData.QueryBuilder/Constants/ODataQuerySeparators.cs +++ b/src/OData.QueryBuilder/Contants/QuerySeparators.cs @@ -1,6 +1,6 @@ namespace OData.QueryBuilder.Constants { - internal struct ODataQuerySeparators + internal struct QuerySeparators { public const string MainString = "&"; diff --git a/src/OData.QueryBuilder/Constants/ODataQuerySorts.cs b/src/OData.QueryBuilder/Contants/QuerySorts.cs similarity index 79% rename from src/OData.QueryBuilder/Constants/ODataQuerySorts.cs rename to src/OData.QueryBuilder/Contants/QuerySorts.cs index 23be4685..49632288 100644 --- a/src/OData.QueryBuilder/Constants/ODataQuerySorts.cs +++ b/src/OData.QueryBuilder/Contants/QuerySorts.cs @@ -1,6 +1,6 @@ namespace OData.QueryBuilder.Constants { - internal struct ODataQuerySorts + internal struct QuerySorts { public const string Asc = "asc"; diff --git a/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs b/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs index 71b929d4..d72a213d 100644 --- a/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs @@ -44,11 +44,11 @@ public static string ConvertToString(object @object) case DateTimeOffset dateTimeOffset: return $"{dateTimeOffset:s}Z"; case IEnumerable intValues: - var intValuesString = string.Join(ODataQuerySeparators.CommaString, intValues); + var intValuesString = string.Join(QuerySeparators.CommaString, intValues); return !string.IsNullOrEmpty(intValuesString) ? intValuesString : default; case IEnumerable stringValues: - var stringValuesString = string.Join($"'{ODataQuerySeparators.CommaString}'", stringValues); + var stringValuesString = string.Join($"'{QuerySeparators.CommaString}'", stringValues); return !string.IsNullOrEmpty(stringValuesString) ? $"'{stringValuesString}'" : default; default: diff --git a/src/OData.QueryBuilder/OData.QueryBuilder.csproj b/src/OData.QueryBuilder/OData.QueryBuilder.csproj index 35593d92..e04f94a7 100644 --- a/src/OData.QueryBuilder/OData.QueryBuilder.csproj +++ b/src/OData.QueryBuilder/OData.QueryBuilder.csproj @@ -14,9 +14,4 @@ Always - - - - - diff --git a/src/OData.QueryBuilder/ODataQuery.cs b/src/OData.QueryBuilder/ODataQuery.cs index b1c04623..87fab452 100644 --- a/src/OData.QueryBuilder/ODataQuery.cs +++ b/src/OData.QueryBuilder/ODataQuery.cs @@ -15,13 +15,13 @@ public ODataQuery(StringBuilder stringBuilder) => public Dictionary ToDictionary() { var odataOperators = _stringBuilder.ToString() - .Split(new char[2] { ODataQuerySeparators.BeginChar, ODataQuerySeparators.MainChar }, StringSplitOptions.RemoveEmptyEntries); + .Split(new char[2] { QuerySeparators.BeginChar, QuerySeparators.MainChar }, StringSplitOptions.RemoveEmptyEntries); var dictionary = new Dictionary(odataOperators.Length - 1); for (var step = 1; step < odataOperators.Length; step++) { - var odataOperator = odataOperators[step].Split(ODataQuerySeparators.EqualSignChar); + var odataOperator = odataOperators[step].Split(QuerySeparators.EqualSignChar); dictionary.Add(odataOperator[0], odataOperator[1]); } @@ -29,6 +29,6 @@ public Dictionary ToDictionary() return dictionary; } - public Uri ToUri() => new Uri(_stringBuilder.ToString().TrimEnd(ODataQuerySeparators.MainChar)); + public Uri ToUri() => new Uri(_stringBuilder.ToString().TrimEnd(QuerySeparators.MainChar)); } } diff --git a/src/OData.QueryBuilder/ODataQueryNested.cs b/src/OData.QueryBuilder/ODataQueryNested.cs index 796b5ea3..463dfb36 100644 --- a/src/OData.QueryBuilder/ODataQueryNested.cs +++ b/src/OData.QueryBuilder/ODataQueryNested.cs @@ -10,6 +10,6 @@ public class ODataQueryNested public ODataQueryNested(StringBuilder queryBuilder) => _stringBuilder = queryBuilder; - public string Query => _stringBuilder.ToString().Trim(ODataQuerySeparators.NestedChar); + public string Query => _stringBuilder.ToString().Trim(QuerySeparators.NestedChar); } } diff --git a/src/OData.QueryBuilder/Parameters/IODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/IODataQueryParameterKey.cs deleted file mode 100644 index e764b894..00000000 --- a/src/OData.QueryBuilder/Parameters/IODataQueryParameterKey.cs +++ /dev/null @@ -1,15 +0,0 @@ -using OData.QueryBuilder.Builders.Nested; -using System; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Parameters -{ - public interface IODataQueryParameterKey : IODataQuery - { - IODataQueryParameterKey Expand(Expression> entityExpand); - - IODataQueryParameterKey Expand(Action> entityExpandNested); - - IODataQueryParameterKey Select(Expression> entitySelect); - } -} diff --git a/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs deleted file mode 100644 index 6b167011..00000000 --- a/src/OData.QueryBuilder/Parameters/IODataQueryParameterList.cs +++ /dev/null @@ -1,33 +0,0 @@ -using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.Functions; -using OData.QueryBuilder.Operators; -using System; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Parameters -{ - public interface IODataQueryParameterList : IODataQuery - { - IODataQueryParameterList Filter(Expression> entityFilter); - - IODataQueryParameterList Filter(Expression> entityFilter); - - IODataQueryParameterList Filter(Expression> entityFilter); - - IODataQueryParameterList Expand(Expression> entityExpand); - - IODataQueryParameterList Expand(Action> entityExpandNested); - - IODataQueryParameterList Select(Expression> entitySelect); - - IODataQueryParameterList OrderBy(Expression> entityOrderBy); - - IODataQueryParameterList OrderByDescending(Expression> entityOrderByDescending); - - IODataQueryParameterList Top(int number); - - IODataQueryParameterList Skip(int number); - - IODataQueryParameterList Count(bool value = true); - } -} \ No newline at end of file diff --git a/src/OData.QueryBuilder/Parameters/Nested/IODataQueryNestedParameter.cs b/src/OData.QueryBuilder/Parameters/Nested/IODataQueryNestedParameter.cs deleted file mode 100644 index 1cf54656..00000000 --- a/src/OData.QueryBuilder/Parameters/Nested/IODataQueryNestedParameter.cs +++ /dev/null @@ -1,23 +0,0 @@ -using OData.QueryBuilder.Builders.Nested; -using System; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Parameters.Nested -{ - public interface IODataQueryNestedParameter - { - IODataQueryNestedParameter Expand(Action> entityExpandNested); - - IODataQueryNestedParameter Expand(Expression> entityNestedExpand); - - IODataQueryNestedParameter Filter(Expression> entityNestedFilter); - - IODataQueryNestedParameter Select(Expression> entityNestedSelect); - - IODataQueryNestedParameter OrderBy(Expression> entityNestedOrderBy); - - IODataQueryNestedParameter OrderByDescending(Expression> entityNestedOrderByDescending); - - IODataQueryNestedParameter Top(int number); - } -} diff --git a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs b/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs deleted file mode 100644 index 79828fda..00000000 --- a/src/OData.QueryBuilder/Parameters/Nested/ODataQueryNestedParameter.cs +++ /dev/null @@ -1,85 +0,0 @@ -using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.Constants; -using OData.QueryBuilder.Visitors; -using System; -using System.Linq.Expressions; -using System.Text; - -namespace OData.QueryBuilder.Parameters.Nested -{ - public class ODataQueryNestedParameter : ODataQueryNested, IODataQueryNestedParameter - { - public ODataQueryNestedParameter() - : base(new StringBuilder()) - { - } - - public IODataQueryNestedParameter Expand(Expression> entityNestedExpand) - { - var visitor = new VisitorExpression(entityNestedExpand.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.NestedString}"); - - return this; - } - - public IODataQueryNestedParameter Expand(Action> actionEntityExpandNested) - { - var builder = new ODataQueryNestedBuilder(); - - actionEntityExpandNested(builder); - - _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{builder.Query}{ODataQuerySeparators.NestedString}"); - - return this; - } - - public IODataQueryNestedParameter Filter(Expression> entityNestedFilter) - { - var visitor = new VisitorExpression(entityNestedFilter.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.NestedString}"); - - return this; - } - - public IODataQueryNestedParameter OrderBy(Expression> entityNestedOrderBy) - { - var visitor = new VisitorExpression(entityNestedOrderBy.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Asc}{ODataQuerySeparators.NestedString}"); - - return this; - } - - public IODataQueryNestedParameter OrderByDescending(Expression> entityNestedOrderByDescending) - { - var visitor = new VisitorExpression(entityNestedOrderByDescending.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Desc}{ODataQuerySeparators.NestedString}"); - - return this; - } - - public IODataQueryNestedParameter Select(Expression> entityNestedSelect) - { - var visitor = new VisitorExpression(entityNestedSelect.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.NestedString}"); - - return this; - } - - public IODataQueryNestedParameter Top(int value) - { - _stringBuilder.Append($"{ODataQueryParameters.Top}{ODataQuerySeparators.EqualSignString}{value}{ODataQuerySeparators.NestedString}"); - - return this; - } - } -} diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs deleted file mode 100644 index 71c9320d..00000000 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterKey.cs +++ /dev/null @@ -1,48 +0,0 @@ -using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.Constants; -using OData.QueryBuilder.Visitors; -using System; -using System.Linq.Expressions; -using System.Text; - -namespace OData.QueryBuilder.Parameters -{ - public class ODataQueryParameterKey : ODataQuery, IODataQueryParameterKey - { - public ODataQueryParameterKey(StringBuilder stringBuilder) - : base(stringBuilder) - { - } - - public IODataQueryParameterKey Expand(Expression> entityExpand) - { - var visitor = new VisitorExpression(entityExpand.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); - - return this; - } - - public IODataQueryParameterKey Expand(Action> actionEntityExpandNested) - { - var builder = new ODataQueryNestedBuilder(); - - actionEntityExpandNested(builder); - - _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{builder.Query}{ODataQuerySeparators.MainString}"); - - return this; - } - - public IODataQueryParameterKey Select(Expression> entitySelect) - { - var visitor = new VisitorExpression(entitySelect.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); - - return this; - } - } -} diff --git a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs b/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs deleted file mode 100644 index 936b2227..00000000 --- a/src/OData.QueryBuilder/Parameters/ODataQueryParameterList.cs +++ /dev/null @@ -1,120 +0,0 @@ -using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.Constants; -using OData.QueryBuilder.Functions; -using OData.QueryBuilder.Operators; -using OData.QueryBuilder.Visitors; -using System; -using System.Linq.Expressions; -using System.Text; - -namespace OData.QueryBuilder.Parameters -{ - public class ODataQueryParameterList : ODataQuery, IODataQueryParameterList - { - public ODataQueryParameterList(StringBuilder stringBuilder) - : base(stringBuilder) - { - } - - public IODataQueryParameterList Filter(Expression> entityFilter) - { - var visitor = new VisitorExpression(entityFilter.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); - - return this; - } - - public IODataQueryParameterList Filter(Expression> entityFilter) - { - var visitor = new VisitorExpression(entityFilter.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); - - return this; - } - - public IODataQueryParameterList Filter(Expression> entityFilter) - { - var visitor = new VisitorExpression(entityFilter.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryParameters.Filter}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); - - return this; - } - - public IODataQueryParameterList Expand(Expression> entityExpand) - { - var visitor = new VisitorExpression(entityExpand.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); - - return this; - } - - public IODataQueryParameterList Expand(Action> entityExpandNested) - { - var builder = new ODataQueryNestedBuilder(); - entityExpandNested(builder); - - _stringBuilder.Append($"{ODataQueryParameters.Expand}{ODataQuerySeparators.EqualSignString}{builder.Query}{ODataQuerySeparators.MainString}"); - - return this; - } - - public IODataQueryParameterList Select(Expression> entitySelect) - { - var visitor = new VisitorExpression(entitySelect.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryParameters.Select}{ODataQuerySeparators.EqualSignString}{query}{ODataQuerySeparators.MainString}"); - - return this; - } - - public IODataQueryParameterList OrderBy(Expression> entityOrderBy) - { - var visitor = new VisitorExpression(entityOrderBy.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Asc}{ODataQuerySeparators.MainString}"); - - return this; - } - - public IODataQueryParameterList OrderByDescending(Expression> entityOrderByDescending) - { - var visitor = new VisitorExpression(entityOrderByDescending.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryParameters.OrderBy}{ODataQuerySeparators.EqualSignString}{query} {ODataQuerySorts.Desc}{ODataQuerySeparators.MainString}"); - - return this; - } - - public IODataQueryParameterList Skip(int value) - { - _stringBuilder.Append($"{ODataQueryParameters.Skip}{ODataQuerySeparators.EqualSignString}{value}{ODataQuerySeparators.MainString}"); - - return this; - } - - public IODataQueryParameterList Top(int value) - { - _stringBuilder.Append($"{ODataQueryParameters.Top}{ODataQuerySeparators.EqualSignString}{value}{ODataQuerySeparators.MainString}"); - - return this; - } - - public IODataQueryParameterList Count(bool value = true) - { - _stringBuilder.Append($"{ODataQueryParameters.Count}{ODataQuerySeparators.EqualSignString}{value.ToString().ToLower()}{ODataQuerySeparators.MainString}"); - - return this; - } - } -} diff --git a/src/OData.QueryBuilder/Resourses/IODataQueryResource.cs b/src/OData.QueryBuilder/Resourses/IODataQueryResource.cs index 95751909..1acde769 100644 --- a/src/OData.QueryBuilder/Resourses/IODataQueryResource.cs +++ b/src/OData.QueryBuilder/Resourses/IODataQueryResource.cs @@ -1,13 +1,13 @@ -using OData.QueryBuilder.Parameters; +using OData.QueryBuilder.V4.Options; namespace OData.QueryBuilder.Resourses { public interface IODataQueryResource { - IODataQueryParameterKey ByKey(int key); + IODataQueryOptionKey ByKey(int key); - IODataQueryParameterKey ByKey(string key); + IODataQueryOptionKey ByKey(string key); - IODataQueryParameterList ByList(); + IODataQueryOptionList ByList(); } } diff --git a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs b/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs index 28a6409e..249a8fc9 100644 --- a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs +++ b/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs @@ -1,5 +1,5 @@ using OData.QueryBuilder.Constants; -using OData.QueryBuilder.Parameters; +using OData.QueryBuilder.V4.Options; using System.Text; namespace OData.QueryBuilder.Resourses @@ -15,25 +15,25 @@ public ODataQueryResource(string resourceUrl, ODataVersion odataVersion) _odataVersion = odataVersion; } - public IODataQueryParameterKey ByKey(int key) + public IODataQueryOptionKey ByKey(int key) { - _stringBuilder.Append($"({key}){ODataQuerySeparators.BeginString}"); + _stringBuilder.Append($"({key}){QuerySeparators.BeginString}"); - return new ODataQueryParameterKey(_stringBuilder); + return new ODataQueryOptionKey(_stringBuilder); } - public IODataQueryParameterKey ByKey(string key) + public IODataQueryOptionKey ByKey(string key) { - _stringBuilder.Append($"('{key}'){ODataQuerySeparators.BeginString}"); + _stringBuilder.Append($"('{key}'){QuerySeparators.BeginString}"); - return new ODataQueryParameterKey(_stringBuilder); + return new ODataQueryOptionKey(_stringBuilder); } - public IODataQueryParameterList ByList() + public IODataQueryOptionList ByList() { - _stringBuilder.Append(ODataQuerySeparators.BeginString); + _stringBuilder.Append(QuerySeparators.BeginString); - return new ODataQueryParameterList(_stringBuilder); + return new ODataQueryOptionList(_stringBuilder); } } } diff --git a/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs b/src/OData.QueryBuilder/V4/Constants/ODataQueryFunctions.cs similarity index 87% rename from src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs rename to src/OData.QueryBuilder/V4/Constants/ODataQueryFunctions.cs index 074fcf87..6fbbdba8 100644 --- a/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs +++ b/src/OData.QueryBuilder/V4/Constants/ODataQueryFunctions.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.Constants +namespace OData.QueryBuilder.V4.Constants { internal struct ODataQueryFunctions { diff --git a/src/OData.QueryBuilder/Constants/ODataQueryOperators.cs b/src/OData.QueryBuilder/V4/Constants/ODataQueryOperators.cs similarity index 79% rename from src/OData.QueryBuilder/Constants/ODataQueryOperators.cs rename to src/OData.QueryBuilder/V4/Constants/ODataQueryOperators.cs index 6a956c71..528259c6 100644 --- a/src/OData.QueryBuilder/Constants/ODataQueryOperators.cs +++ b/src/OData.QueryBuilder/V4/Constants/ODataQueryOperators.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.Constants +namespace OData.QueryBuilder.V4.Constants { internal struct ODataQueryOperators { diff --git a/src/OData.QueryBuilder/Constants/ODataQueryParameters.cs b/src/OData.QueryBuilder/V4/Constants/ODataQueryOptions.cs similarity index 80% rename from src/OData.QueryBuilder/Constants/ODataQueryParameters.cs rename to src/OData.QueryBuilder/V4/Constants/ODataQueryOptions.cs index b7282538..e9ea8383 100644 --- a/src/OData.QueryBuilder/Constants/ODataQueryParameters.cs +++ b/src/OData.QueryBuilder/V4/Constants/ODataQueryOptions.cs @@ -1,6 +1,6 @@ -namespace OData.QueryBuilder.Constants +namespace OData.QueryBuilder.V4.Constants { - internal struct ODataQueryParameters + internal struct ODataQueryOptions { public const string Select = "$select"; diff --git a/src/OData.QueryBuilder/Functions/IConvertFunction.cs b/src/OData.QueryBuilder/V4/Functions/IConvertFunction.cs similarity index 87% rename from src/OData.QueryBuilder/Functions/IConvertFunction.cs rename to src/OData.QueryBuilder/V4/Functions/IConvertFunction.cs index 8fd1bea0..74c47156 100644 --- a/src/OData.QueryBuilder/Functions/IConvertFunction.cs +++ b/src/OData.QueryBuilder/V4/Functions/IConvertFunction.cs @@ -1,6 +1,6 @@ using System; -namespace OData.QueryBuilder.Functions +namespace OData.QueryBuilder.V4.Functions { public interface IConvertFunction { diff --git a/src/OData.QueryBuilder/Functions/IODataQueryDateFunction.cs b/src/OData.QueryBuilder/V4/Functions/IODataQueryDateFunction.cs similarity index 86% rename from src/OData.QueryBuilder/Functions/IODataQueryDateFunction.cs rename to src/OData.QueryBuilder/V4/Functions/IODataQueryDateFunction.cs index ddb93f03..7f64b048 100644 --- a/src/OData.QueryBuilder/Functions/IODataQueryDateFunction.cs +++ b/src/OData.QueryBuilder/V4/Functions/IODataQueryDateFunction.cs @@ -1,6 +1,6 @@ using System; -namespace OData.QueryBuilder.Functions +namespace OData.QueryBuilder.V4.Functions { public interface IODataQueryDateFunction { diff --git a/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs b/src/OData.QueryBuilder/V4/Functions/IODataQueryFunction.cs similarity index 73% rename from src/OData.QueryBuilder/Functions/IODataQueryFunction.cs rename to src/OData.QueryBuilder/V4/Functions/IODataQueryFunction.cs index d99db72c..ad9b9822 100644 --- a/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs +++ b/src/OData.QueryBuilder/V4/Functions/IODataQueryFunction.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.Functions +namespace OData.QueryBuilder.V4.Functions { public interface IODataQueryFunction : IODataQueryStringFunction, IODataQueryDateFunction, IConvertFunction { diff --git a/src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs b/src/OData.QueryBuilder/V4/Functions/IODataQueryStringFunction.cs similarity index 94% rename from src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs rename to src/OData.QueryBuilder/V4/Functions/IODataQueryStringFunction.cs index f7105073..73646866 100644 --- a/src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs +++ b/src/OData.QueryBuilder/V4/Functions/IODataQueryStringFunction.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.Functions +namespace OData.QueryBuilder.V4.Functions { public interface IODataQueryStringFunction { diff --git a/src/OData.QueryBuilder/Operators/IODataQueryOperator.cs b/src/OData.QueryBuilder/V4/Operators/IODataQueryOperator.cs similarity index 87% rename from src/OData.QueryBuilder/Operators/IODataQueryOperator.cs rename to src/OData.QueryBuilder/V4/Operators/IODataQueryOperator.cs index 1f4c09c4..fb8fba0c 100644 --- a/src/OData.QueryBuilder/Operators/IODataQueryOperator.cs +++ b/src/OData.QueryBuilder/V4/Operators/IODataQueryOperator.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace OData.QueryBuilder.Operators +namespace OData.QueryBuilder.V4.Operators { public interface IODataQueryOperator { diff --git a/src/OData.QueryBuilder/V4/Options/IODataQueryOptionKey.cs b/src/OData.QueryBuilder/V4/Options/IODataQueryOptionKey.cs new file mode 100644 index 00000000..6042060e --- /dev/null +++ b/src/OData.QueryBuilder/V4/Options/IODataQueryOptionKey.cs @@ -0,0 +1,15 @@ +using OData.QueryBuilder.Builders.Nested; +using System; +using System.Linq.Expressions; + +namespace OData.QueryBuilder.V4.Options +{ + public interface IODataQueryOptionKey : IODataQuery + { + IODataQueryOptionKey Expand(Expression> entityExpand); + + IODataQueryOptionKey Expand(Action> entityExpandNested); + + IODataQueryOptionKey Select(Expression> entitySelect); + } +} diff --git a/src/OData.QueryBuilder/V4/Options/IODataQueryOptionList.cs b/src/OData.QueryBuilder/V4/Options/IODataQueryOptionList.cs new file mode 100644 index 00000000..46a69d38 --- /dev/null +++ b/src/OData.QueryBuilder/V4/Options/IODataQueryOptionList.cs @@ -0,0 +1,33 @@ +using OData.QueryBuilder.Builders.Nested; +using OData.QueryBuilder.V4.Functions; +using OData.QueryBuilder.V4.Operators; +using System; +using System.Linq.Expressions; + +namespace OData.QueryBuilder.V4.Options +{ + public interface IODataQueryOptionList : IODataQuery + { + IODataQueryOptionList Filter(Expression> entityFilter); + + IODataQueryOptionList Filter(Expression> entityFilter); + + IODataQueryOptionList Filter(Expression> entityFilter); + + IODataQueryOptionList Expand(Expression> entityExpand); + + IODataQueryOptionList Expand(Action> entityExpandNested); + + IODataQueryOptionList Select(Expression> entitySelect); + + IODataQueryOptionList OrderBy(Expression> entityOrderBy); + + IODataQueryOptionList OrderByDescending(Expression> entityOrderByDescending); + + IODataQueryOptionList Top(int number); + + IODataQueryOptionList Skip(int number); + + IODataQueryOptionList Count(bool value = true); + } +} \ No newline at end of file diff --git a/src/OData.QueryBuilder/V4/Options/Nested/IODataQueryOptionNested.cs b/src/OData.QueryBuilder/V4/Options/Nested/IODataQueryOptionNested.cs new file mode 100644 index 00000000..11c9e93d --- /dev/null +++ b/src/OData.QueryBuilder/V4/Options/Nested/IODataQueryOptionNested.cs @@ -0,0 +1,23 @@ +using OData.QueryBuilder.Builders.Nested; +using System; +using System.Linq.Expressions; + +namespace OData.QueryBuilder.V4.Options.Nested +{ + public interface IODataQueryOptionNested + { + IODataQueryOptionNested Expand(Action> entityExpandNested); + + IODataQueryOptionNested Expand(Expression> entityNestedExpand); + + IODataQueryOptionNested Filter(Expression> entityNestedFilter); + + IODataQueryOptionNested Select(Expression> entityNestedSelect); + + IODataQueryOptionNested OrderBy(Expression> entityNestedOrderBy); + + IODataQueryOptionNested OrderByDescending(Expression> entityNestedOrderByDescending); + + IODataQueryOptionNested Top(int number); + } +} diff --git a/src/OData.QueryBuilder/V4/Options/Nested/ODataQueryOptionNested.cs b/src/OData.QueryBuilder/V4/Options/Nested/ODataQueryOptionNested.cs new file mode 100644 index 00000000..ba372c81 --- /dev/null +++ b/src/OData.QueryBuilder/V4/Options/Nested/ODataQueryOptionNested.cs @@ -0,0 +1,86 @@ +using OData.QueryBuilder.Builders.Nested; +using OData.QueryBuilder.Constants; +using OData.QueryBuilder.V4.Constants; +using OData.QueryBuilder.Visitors; +using System; +using System.Linq.Expressions; +using System.Text; + +namespace OData.QueryBuilder.V4.Options.Nested +{ + public class ODataQueryOptionNested : ODataQueryNested, IODataQueryOptionNested + { + public ODataQueryOptionNested() + : base(new StringBuilder()) + { + } + + public IODataQueryOptionNested Expand(Expression> entityNestedExpand) + { + var visitor = new VisitorExpression(entityNestedExpand.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataQueryOptions.Expand}{QuerySeparators.EqualSignString}{query}{QuerySeparators.NestedString}"); + + return this; + } + + public IODataQueryOptionNested Expand(Action> actionEntityExpandNested) + { + var builder = new ODataQueryNestedBuilder(); + + actionEntityExpandNested(builder); + + _stringBuilder.Append($"{ODataQueryOptions.Expand}{QuerySeparators.EqualSignString}{builder.Query}{QuerySeparators.NestedString}"); + + return this; + } + + public IODataQueryOptionNested Filter(Expression> entityNestedFilter) + { + var visitor = new VisitorExpression(entityNestedFilter.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataQueryOptions.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.NestedString}"); + + return this; + } + + public IODataQueryOptionNested OrderBy(Expression> entityNestedOrderBy) + { + var visitor = new VisitorExpression(entityNestedOrderBy.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataQueryOptions.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Asc}{QuerySeparators.NestedString}"); + + return this; + } + + public IODataQueryOptionNested OrderByDescending(Expression> entityNestedOrderByDescending) + { + var visitor = new VisitorExpression(entityNestedOrderByDescending.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataQueryOptions.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Desc}{QuerySeparators.NestedString}"); + + return this; + } + + public IODataQueryOptionNested Select(Expression> entityNestedSelect) + { + var visitor = new VisitorExpression(entityNestedSelect.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataQueryOptions.Select}{QuerySeparators.EqualSignString}{query}{QuerySeparators.NestedString}"); + + return this; + } + + public IODataQueryOptionNested Top(int value) + { + _stringBuilder.Append($"{ODataQueryOptions.Top}{QuerySeparators.EqualSignString}{value}{QuerySeparators.NestedString}"); + + return this; + } + } +} diff --git a/src/OData.QueryBuilder/V4/Options/ODataQueryOptionKey.cs b/src/OData.QueryBuilder/V4/Options/ODataQueryOptionKey.cs new file mode 100644 index 00000000..1d353eb6 --- /dev/null +++ b/src/OData.QueryBuilder/V4/Options/ODataQueryOptionKey.cs @@ -0,0 +1,49 @@ +using OData.QueryBuilder.Builders.Nested; +using OData.QueryBuilder.Constants; +using OData.QueryBuilder.V4.Constants; +using OData.QueryBuilder.Visitors; +using System; +using System.Linq.Expressions; +using System.Text; + +namespace OData.QueryBuilder.V4.Options +{ + public class ODataQueryOptionKey : ODataQuery, IODataQueryOptionKey + { + public ODataQueryOptionKey(StringBuilder stringBuilder) + : base(stringBuilder) + { + } + + public IODataQueryOptionKey Expand(Expression> entityExpand) + { + var visitor = new VisitorExpression(entityExpand.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataQueryOptions.Expand}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataQueryOptionKey Expand(Action> actionEntityExpandNested) + { + var builder = new ODataQueryNestedBuilder(); + + actionEntityExpandNested(builder); + + _stringBuilder.Append($"{ODataQueryOptions.Expand}{QuerySeparators.EqualSignString}{builder.Query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataQueryOptionKey Select(Expression> entitySelect) + { + var visitor = new VisitorExpression(entitySelect.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataQueryOptions.Select}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); + + return this; + } + } +} diff --git a/src/OData.QueryBuilder/V4/Options/ODataQueryOptionList.cs b/src/OData.QueryBuilder/V4/Options/ODataQueryOptionList.cs new file mode 100644 index 00000000..d0543afa --- /dev/null +++ b/src/OData.QueryBuilder/V4/Options/ODataQueryOptionList.cs @@ -0,0 +1,121 @@ +using OData.QueryBuilder.Builders.Nested; +using OData.QueryBuilder.Constants; +using OData.QueryBuilder.V4.Constants; +using OData.QueryBuilder.V4.Functions; +using OData.QueryBuilder.V4.Operators; +using OData.QueryBuilder.Visitors; +using System; +using System.Linq.Expressions; +using System.Text; + +namespace OData.QueryBuilder.V4.Options +{ + public class ODataQueryOptionList : ODataQuery, IODataQueryOptionList + { + public ODataQueryOptionList(StringBuilder stringBuilder) + : base(stringBuilder) + { + } + + public IODataQueryOptionList Filter(Expression> entityFilter) + { + var visitor = new VisitorExpression(entityFilter.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataQueryOptions.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataQueryOptionList Filter(Expression> entityFilter) + { + var visitor = new VisitorExpression(entityFilter.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataQueryOptions.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataQueryOptionList Filter(Expression> entityFilter) + { + var visitor = new VisitorExpression(entityFilter.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataQueryOptions.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataQueryOptionList Expand(Expression> entityExpand) + { + var visitor = new VisitorExpression(entityExpand.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataQueryOptions.Expand}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataQueryOptionList Expand(Action> entityExpandNested) + { + var builder = new ODataQueryNestedBuilder(); + entityExpandNested(builder); + + _stringBuilder.Append($"{ODataQueryOptions.Expand}{QuerySeparators.EqualSignString}{builder.Query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataQueryOptionList Select(Expression> entitySelect) + { + var visitor = new VisitorExpression(entitySelect.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataQueryOptions.Select}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataQueryOptionList OrderBy(Expression> entityOrderBy) + { + var visitor = new VisitorExpression(entityOrderBy.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataQueryOptions.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Asc}{QuerySeparators.MainString}"); + + return this; + } + + public IODataQueryOptionList OrderByDescending(Expression> entityOrderByDescending) + { + var visitor = new VisitorExpression(entityOrderByDescending.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataQueryOptions.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Desc}{QuerySeparators.MainString}"); + + return this; + } + + public IODataQueryOptionList Skip(int value) + { + _stringBuilder.Append($"{ODataQueryOptions.Skip}{QuerySeparators.EqualSignString}{value}{QuerySeparators.MainString}"); + + return this; + } + + public IODataQueryOptionList Top(int value) + { + _stringBuilder.Append($"{ODataQueryOptions.Top}{QuerySeparators.EqualSignString}{value}{QuerySeparators.MainString}"); + + return this; + } + + public IODataQueryOptionList Count(bool value = true) + { + _stringBuilder.Append($"{ODataQueryOptions.Count}{QuerySeparators.EqualSignString}{value.ToString().ToLower()}{QuerySeparators.MainString}"); + + return this; + } + } +} diff --git a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs index 0f674330..b04076a3 100644 --- a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs +++ b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs @@ -1,7 +1,8 @@ using OData.QueryBuilder.Constants; using OData.QueryBuilder.Extensions; -using OData.QueryBuilder.Functions; -using OData.QueryBuilder.Operators; +using OData.QueryBuilder.V4.Constants; +using OData.QueryBuilder.V4.Functions; +using OData.QueryBuilder.V4.Operators; using System; using System.Linq.Expressions; @@ -136,7 +137,7 @@ protected string VisitNewExpression(NewExpression newExpression) names[i] = newExpression.Members[i].Name; } - return string.Join(ODataQuerySeparators.CommaString, names); + return string.Join(QuerySeparators.CommaString, names); } protected string VisitUnaryExpression(UnaryExpression unaryExpression) diff --git a/test/OData.QueryBuilder.Test/ODataQueryParameterKeyTest.cs b/test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs similarity index 97% rename from test/OData.QueryBuilder.Test/ODataQueryParameterKeyTest.cs rename to test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs index 2cbdad7d..86f74fea 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryParameterKeyTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs @@ -6,11 +6,11 @@ namespace OData.QueryBuilder.Test { - public class ODataQueryParameterKeyTest : IClassFixture + public class ODataQueryOptionKeyTest : IClassFixture { private readonly ODataQueryBuilder _odataQueryBuilder; - public ODataQueryParameterKeyTest(CommonFixture commonFixture) => + public ODataQueryOptionKeyTest(CommonFixture commonFixture) => _odataQueryBuilder = commonFixture.ODataQueryBuilder1; [Fact(DisplayName = "Expand simple => Success")] diff --git a/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs b/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs similarity index 99% rename from test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs rename to test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs index f7ba48e4..674b185c 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryParameterListTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs @@ -8,13 +8,13 @@ namespace OData.QueryBuilder.Test { - public class ODataQueryParameterListTest : IClassFixture + public class ODataQueryOptionListTest : IClassFixture { private readonly ODataQueryBuilder _odataQueryBuilder; public static string IdCodeStatic => "testCode"; - public ODataQueryParameterListTest(CommonFixture commonFixture) => + public ODataQueryOptionListTest(CommonFixture commonFixture) => _odataQueryBuilder = commonFixture.ODataQueryBuilder2; [Fact(DisplayName = "Expand simple => Success")] From ac3a25a87fff0951b9a94012afbd9adacf65ef02 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Tue, 23 Jun 2020 22:29:25 +0300 Subject: [PATCH 28/76] #ZEX#undo --- .../Builders/Nested/IODataQueryNestedBuilder.cs | 2 +- .../Builders/Nested/ODataQueryNestedBuilder.cs | 2 +- src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs | 9 +++------ .../{V4 => }/Constants/ODataQueryFunctions.cs | 2 +- .../{V4 => }/Constants/ODataQueryOperators.cs | 2 +- .../{V4 => }/Constants/ODataQueryOptions.cs | 2 +- .../{Contants => Constants}/QuerySeparators.cs | 0 .../{Contants => Constants}/QuerySorts.cs | 0 .../{V4 => }/Functions/IConvertFunction.cs | 2 +- .../{V4 => }/Functions/IODataQueryDateFunction.cs | 2 +- .../{V4 => }/Functions/IODataQueryFunction.cs | 2 +- .../{V4 => }/Functions/IODataQueryStringFunction.cs | 2 +- src/OData.QueryBuilder/ODataVersion.cs | 9 --------- .../{V4 => }/Operators/IODataQueryOperator.cs | 2 +- .../{V4 => }/Options/IODataQueryOptionKey.cs | 2 +- .../{V4 => }/Options/IODataQueryOptionList.cs | 6 +++--- .../{V4 => }/Options/Nested/IODataQueryOptionNested.cs | 2 +- .../{V4 => }/Options/Nested/ODataQueryOptionNested.cs | 3 +-- .../{V4 => }/Options/ODataQueryOptionKey.cs | 3 +-- .../{V4 => }/Options/ODataQueryOptionList.cs | 7 +++---- src/OData.QueryBuilder/Resourses/IODataQueryResource.cs | 2 +- src/OData.QueryBuilder/Resourses/ODataQueryResource.cs | 6 ++---- src/OData.QueryBuilder/Visitors/VisitorExpression.cs | 5 ++--- 23 files changed, 28 insertions(+), 46 deletions(-) rename src/OData.QueryBuilder/{V4 => }/Constants/ODataQueryFunctions.cs (87%) rename src/OData.QueryBuilder/{V4 => }/Constants/ODataQueryOperators.cs (79%) rename src/OData.QueryBuilder/{V4 => }/Constants/ODataQueryOptions.cs (89%) rename src/OData.QueryBuilder/{Contants => Constants}/QuerySeparators.cs (100%) rename src/OData.QueryBuilder/{Contants => Constants}/QuerySorts.cs (100%) rename src/OData.QueryBuilder/{V4 => }/Functions/IConvertFunction.cs (87%) rename src/OData.QueryBuilder/{V4 => }/Functions/IODataQueryDateFunction.cs (86%) rename src/OData.QueryBuilder/{V4 => }/Functions/IODataQueryFunction.cs (73%) rename src/OData.QueryBuilder/{V4 => }/Functions/IODataQueryStringFunction.cs (94%) delete mode 100644 src/OData.QueryBuilder/ODataVersion.cs rename src/OData.QueryBuilder/{V4 => }/Operators/IODataQueryOperator.cs (87%) rename src/OData.QueryBuilder/{V4 => }/Options/IODataQueryOptionKey.cs (92%) rename src/OData.QueryBuilder/{V4 => }/Options/IODataQueryOptionList.cs (91%) rename src/OData.QueryBuilder/{V4 => }/Options/Nested/IODataQueryOptionNested.cs (94%) rename src/OData.QueryBuilder/{V4 => }/Options/Nested/ODataQueryOptionNested.cs (97%) rename src/OData.QueryBuilder/{V4 => }/Options/ODataQueryOptionKey.cs (95%) rename src/OData.QueryBuilder/{V4 => }/Options/ODataQueryOptionList.cs (96%) diff --git a/src/OData.QueryBuilder/Builders/Nested/IODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/Nested/IODataQueryNestedBuilder.cs index 0bb400cd..7df6c54a 100644 --- a/src/OData.QueryBuilder/Builders/Nested/IODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/Nested/IODataQueryNestedBuilder.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.V4.Options.Nested; +using OData.QueryBuilder.Options.Nested; using System; using System.Linq.Expressions; diff --git a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs index f9958413..d38e60b1 100644 --- a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.V4.Options.Nested; +using OData.QueryBuilder.Options.Nested; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index 67842770..fe0bd555 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -9,18 +9,15 @@ namespace OData.QueryBuilder.Builders public class ODataQueryBuilder : IODataQueryBuilder { private readonly string _baseUrl; - private readonly ODataVersion _odataVersion; - public ODataQueryBuilder(Uri baseUrl, ODataVersion odataVersion = ODataVersion.V4) + public ODataQueryBuilder(Uri baseUrl) { _baseUrl = $"{baseUrl.OriginalString.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"; - _odataVersion = odataVersion; } - public ODataQueryBuilder(string baseUrl, ODataVersion odataVersion = ODataVersion.V4) + public ODataQueryBuilder(string baseUrl) { _baseUrl = $"{baseUrl.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"; - _odataVersion = odataVersion; } public IODataQueryResource For(Expression> entityResource) @@ -28,7 +25,7 @@ public IODataQueryResource For(Expression($"{_baseUrl}{query}", _odataVersion); + return new ODataQueryResource($"{_baseUrl}{query}"); } } } \ No newline at end of file diff --git a/src/OData.QueryBuilder/V4/Constants/ODataQueryFunctions.cs b/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs similarity index 87% rename from src/OData.QueryBuilder/V4/Constants/ODataQueryFunctions.cs rename to src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs index 6fbbdba8..074fcf87 100644 --- a/src/OData.QueryBuilder/V4/Constants/ODataQueryFunctions.cs +++ b/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.V4.Constants +namespace OData.QueryBuilder.Constants { internal struct ODataQueryFunctions { diff --git a/src/OData.QueryBuilder/V4/Constants/ODataQueryOperators.cs b/src/OData.QueryBuilder/Constants/ODataQueryOperators.cs similarity index 79% rename from src/OData.QueryBuilder/V4/Constants/ODataQueryOperators.cs rename to src/OData.QueryBuilder/Constants/ODataQueryOperators.cs index 528259c6..6a956c71 100644 --- a/src/OData.QueryBuilder/V4/Constants/ODataQueryOperators.cs +++ b/src/OData.QueryBuilder/Constants/ODataQueryOperators.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.V4.Constants +namespace OData.QueryBuilder.Constants { internal struct ODataQueryOperators { diff --git a/src/OData.QueryBuilder/V4/Constants/ODataQueryOptions.cs b/src/OData.QueryBuilder/Constants/ODataQueryOptions.cs similarity index 89% rename from src/OData.QueryBuilder/V4/Constants/ODataQueryOptions.cs rename to src/OData.QueryBuilder/Constants/ODataQueryOptions.cs index e9ea8383..cecb9da7 100644 --- a/src/OData.QueryBuilder/V4/Constants/ODataQueryOptions.cs +++ b/src/OData.QueryBuilder/Constants/ODataQueryOptions.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.V4.Constants +namespace OData.QueryBuilder.Constants { internal struct ODataQueryOptions { diff --git a/src/OData.QueryBuilder/Contants/QuerySeparators.cs b/src/OData.QueryBuilder/Constants/QuerySeparators.cs similarity index 100% rename from src/OData.QueryBuilder/Contants/QuerySeparators.cs rename to src/OData.QueryBuilder/Constants/QuerySeparators.cs diff --git a/src/OData.QueryBuilder/Contants/QuerySorts.cs b/src/OData.QueryBuilder/Constants/QuerySorts.cs similarity index 100% rename from src/OData.QueryBuilder/Contants/QuerySorts.cs rename to src/OData.QueryBuilder/Constants/QuerySorts.cs diff --git a/src/OData.QueryBuilder/V4/Functions/IConvertFunction.cs b/src/OData.QueryBuilder/Functions/IConvertFunction.cs similarity index 87% rename from src/OData.QueryBuilder/V4/Functions/IConvertFunction.cs rename to src/OData.QueryBuilder/Functions/IConvertFunction.cs index 74c47156..8fd1bea0 100644 --- a/src/OData.QueryBuilder/V4/Functions/IConvertFunction.cs +++ b/src/OData.QueryBuilder/Functions/IConvertFunction.cs @@ -1,6 +1,6 @@ using System; -namespace OData.QueryBuilder.V4.Functions +namespace OData.QueryBuilder.Functions { public interface IConvertFunction { diff --git a/src/OData.QueryBuilder/V4/Functions/IODataQueryDateFunction.cs b/src/OData.QueryBuilder/Functions/IODataQueryDateFunction.cs similarity index 86% rename from src/OData.QueryBuilder/V4/Functions/IODataQueryDateFunction.cs rename to src/OData.QueryBuilder/Functions/IODataQueryDateFunction.cs index 7f64b048..ddb93f03 100644 --- a/src/OData.QueryBuilder/V4/Functions/IODataQueryDateFunction.cs +++ b/src/OData.QueryBuilder/Functions/IODataQueryDateFunction.cs @@ -1,6 +1,6 @@ using System; -namespace OData.QueryBuilder.V4.Functions +namespace OData.QueryBuilder.Functions { public interface IODataQueryDateFunction { diff --git a/src/OData.QueryBuilder/V4/Functions/IODataQueryFunction.cs b/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs similarity index 73% rename from src/OData.QueryBuilder/V4/Functions/IODataQueryFunction.cs rename to src/OData.QueryBuilder/Functions/IODataQueryFunction.cs index ad9b9822..d99db72c 100644 --- a/src/OData.QueryBuilder/V4/Functions/IODataQueryFunction.cs +++ b/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.V4.Functions +namespace OData.QueryBuilder.Functions { public interface IODataQueryFunction : IODataQueryStringFunction, IODataQueryDateFunction, IConvertFunction { diff --git a/src/OData.QueryBuilder/V4/Functions/IODataQueryStringFunction.cs b/src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs similarity index 94% rename from src/OData.QueryBuilder/V4/Functions/IODataQueryStringFunction.cs rename to src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs index 73646866..f7105073 100644 --- a/src/OData.QueryBuilder/V4/Functions/IODataQueryStringFunction.cs +++ b/src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.V4.Functions +namespace OData.QueryBuilder.Functions { public interface IODataQueryStringFunction { diff --git a/src/OData.QueryBuilder/ODataVersion.cs b/src/OData.QueryBuilder/ODataVersion.cs deleted file mode 100644 index cdb84e8c..00000000 --- a/src/OData.QueryBuilder/ODataVersion.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace OData.QueryBuilder -{ - public enum ODataVersion - { - V2, - V3, - V4 - } -} diff --git a/src/OData.QueryBuilder/V4/Operators/IODataQueryOperator.cs b/src/OData.QueryBuilder/Operators/IODataQueryOperator.cs similarity index 87% rename from src/OData.QueryBuilder/V4/Operators/IODataQueryOperator.cs rename to src/OData.QueryBuilder/Operators/IODataQueryOperator.cs index fb8fba0c..1f4c09c4 100644 --- a/src/OData.QueryBuilder/V4/Operators/IODataQueryOperator.cs +++ b/src/OData.QueryBuilder/Operators/IODataQueryOperator.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace OData.QueryBuilder.V4.Operators +namespace OData.QueryBuilder.Operators { public interface IODataQueryOperator { diff --git a/src/OData.QueryBuilder/V4/Options/IODataQueryOptionKey.cs b/src/OData.QueryBuilder/Options/IODataQueryOptionKey.cs similarity index 92% rename from src/OData.QueryBuilder/V4/Options/IODataQueryOptionKey.cs rename to src/OData.QueryBuilder/Options/IODataQueryOptionKey.cs index 6042060e..9326c747 100644 --- a/src/OData.QueryBuilder/V4/Options/IODataQueryOptionKey.cs +++ b/src/OData.QueryBuilder/Options/IODataQueryOptionKey.cs @@ -2,7 +2,7 @@ using System; using System.Linq.Expressions; -namespace OData.QueryBuilder.V4.Options +namespace OData.QueryBuilder.Options { public interface IODataQueryOptionKey : IODataQuery { diff --git a/src/OData.QueryBuilder/V4/Options/IODataQueryOptionList.cs b/src/OData.QueryBuilder/Options/IODataQueryOptionList.cs similarity index 91% rename from src/OData.QueryBuilder/V4/Options/IODataQueryOptionList.cs rename to src/OData.QueryBuilder/Options/IODataQueryOptionList.cs index 46a69d38..ac4c3580 100644 --- a/src/OData.QueryBuilder/V4/Options/IODataQueryOptionList.cs +++ b/src/OData.QueryBuilder/Options/IODataQueryOptionList.cs @@ -1,10 +1,10 @@ using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.V4.Functions; -using OData.QueryBuilder.V4.Operators; +using OData.QueryBuilder.Functions; +using OData.QueryBuilder.Operators; using System; using System.Linq.Expressions; -namespace OData.QueryBuilder.V4.Options +namespace OData.QueryBuilder.Options { public interface IODataQueryOptionList : IODataQuery { diff --git a/src/OData.QueryBuilder/V4/Options/Nested/IODataQueryOptionNested.cs b/src/OData.QueryBuilder/Options/Nested/IODataQueryOptionNested.cs similarity index 94% rename from src/OData.QueryBuilder/V4/Options/Nested/IODataQueryOptionNested.cs rename to src/OData.QueryBuilder/Options/Nested/IODataQueryOptionNested.cs index 11c9e93d..49cd02f9 100644 --- a/src/OData.QueryBuilder/V4/Options/Nested/IODataQueryOptionNested.cs +++ b/src/OData.QueryBuilder/Options/Nested/IODataQueryOptionNested.cs @@ -2,7 +2,7 @@ using System; using System.Linq.Expressions; -namespace OData.QueryBuilder.V4.Options.Nested +namespace OData.QueryBuilder.Options.Nested { public interface IODataQueryOptionNested { diff --git a/src/OData.QueryBuilder/V4/Options/Nested/ODataQueryOptionNested.cs b/src/OData.QueryBuilder/Options/Nested/ODataQueryOptionNested.cs similarity index 97% rename from src/OData.QueryBuilder/V4/Options/Nested/ODataQueryOptionNested.cs rename to src/OData.QueryBuilder/Options/Nested/ODataQueryOptionNested.cs index ba372c81..31a9a14a 100644 --- a/src/OData.QueryBuilder/V4/Options/Nested/ODataQueryOptionNested.cs +++ b/src/OData.QueryBuilder/Options/Nested/ODataQueryOptionNested.cs @@ -1,12 +1,11 @@ using OData.QueryBuilder.Builders.Nested; using OData.QueryBuilder.Constants; -using OData.QueryBuilder.V4.Constants; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; using System.Text; -namespace OData.QueryBuilder.V4.Options.Nested +namespace OData.QueryBuilder.Options.Nested { public class ODataQueryOptionNested : ODataQueryNested, IODataQueryOptionNested { diff --git a/src/OData.QueryBuilder/V4/Options/ODataQueryOptionKey.cs b/src/OData.QueryBuilder/Options/ODataQueryOptionKey.cs similarity index 95% rename from src/OData.QueryBuilder/V4/Options/ODataQueryOptionKey.cs rename to src/OData.QueryBuilder/Options/ODataQueryOptionKey.cs index 1d353eb6..9c4f4c49 100644 --- a/src/OData.QueryBuilder/V4/Options/ODataQueryOptionKey.cs +++ b/src/OData.QueryBuilder/Options/ODataQueryOptionKey.cs @@ -1,12 +1,11 @@ using OData.QueryBuilder.Builders.Nested; using OData.QueryBuilder.Constants; -using OData.QueryBuilder.V4.Constants; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; using System.Text; -namespace OData.QueryBuilder.V4.Options +namespace OData.QueryBuilder.Options { public class ODataQueryOptionKey : ODataQuery, IODataQueryOptionKey { diff --git a/src/OData.QueryBuilder/V4/Options/ODataQueryOptionList.cs b/src/OData.QueryBuilder/Options/ODataQueryOptionList.cs similarity index 96% rename from src/OData.QueryBuilder/V4/Options/ODataQueryOptionList.cs rename to src/OData.QueryBuilder/Options/ODataQueryOptionList.cs index d0543afa..055ad122 100644 --- a/src/OData.QueryBuilder/V4/Options/ODataQueryOptionList.cs +++ b/src/OData.QueryBuilder/Options/ODataQueryOptionList.cs @@ -1,14 +1,13 @@ using OData.QueryBuilder.Builders.Nested; using OData.QueryBuilder.Constants; -using OData.QueryBuilder.V4.Constants; -using OData.QueryBuilder.V4.Functions; -using OData.QueryBuilder.V4.Operators; +using OData.QueryBuilder.Functions; +using OData.QueryBuilder.Operators; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; using System.Text; -namespace OData.QueryBuilder.V4.Options +namespace OData.QueryBuilder.Options { public class ODataQueryOptionList : ODataQuery, IODataQueryOptionList { diff --git a/src/OData.QueryBuilder/Resourses/IODataQueryResource.cs b/src/OData.QueryBuilder/Resourses/IODataQueryResource.cs index 1acde769..dc6b1184 100644 --- a/src/OData.QueryBuilder/Resourses/IODataQueryResource.cs +++ b/src/OData.QueryBuilder/Resourses/IODataQueryResource.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.V4.Options; +using OData.QueryBuilder.Options; namespace OData.QueryBuilder.Resourses { diff --git a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs b/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs index 249a8fc9..e5822412 100644 --- a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs +++ b/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs @@ -1,5 +1,5 @@ using OData.QueryBuilder.Constants; -using OData.QueryBuilder.V4.Options; +using OData.QueryBuilder.Options; using System.Text; namespace OData.QueryBuilder.Resourses @@ -7,12 +7,10 @@ namespace OData.QueryBuilder.Resourses public class ODataQueryResource : IODataQueryResource { private readonly StringBuilder _stringBuilder; - private readonly ODataVersion _odataVersion; - public ODataQueryResource(string resourceUrl, ODataVersion odataVersion) + public ODataQueryResource(string resourceUrl) { _stringBuilder = new StringBuilder(resourceUrl); - _odataVersion = odataVersion; } public IODataQueryOptionKey ByKey(int key) diff --git a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs index b04076a3..04938c0e 100644 --- a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs +++ b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs @@ -1,8 +1,7 @@ using OData.QueryBuilder.Constants; using OData.QueryBuilder.Extensions; -using OData.QueryBuilder.V4.Constants; -using OData.QueryBuilder.V4.Functions; -using OData.QueryBuilder.V4.Operators; +using OData.QueryBuilder.Functions; +using OData.QueryBuilder.Operators; using System; using System.Linq.Expressions; From 5641a2bafb29fdf5e34b0faa3b88f78f8aee1b7a Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Tue, 23 Jun 2020 22:42:32 +0300 Subject: [PATCH 29/76] #ZEXSM#review --- .../Builders/IODataQueryBuilder.cs | 2 +- .../Builders/IODataQueryNestedBuilder.cs | 11 ++ .../Nested/IODataQueryNestedBuilder.cs | 11 -- .../Builders/ODataQueryBuilder.cs | 4 +- .../{Nested => }/ODataQueryNestedBuilder.cs | 8 +- .../Builders/Resourses/IODataQueryResource.cs | 13 ++ .../Resourses/ODataQueryResource.cs | 14 +- ...ueryFunctions.cs => ODataFunctionNames.cs} | 2 +- ...ueryOperators.cs => ODataOperatorNames.cs} | 2 +- ...ataQueryOptions.cs => ODataOptionNames.cs} | 2 +- ...yDateFunction.cs => IODataDateFunction.cs} | 2 +- .../Functions/IODataFunction.cs | 6 + .../Functions/IODataQueryFunction.cs | 6 - ...ingFunction.cs => IODataStringFunction.cs} | 2 +- ...DataQueryOperator.cs => IODataOperator.cs} | 2 +- .../Options/IODataOptionKey.cs | 15 +++ .../Options/IODataOptionList.cs | 33 +++++ .../Options/IODataQueryOptionKey.cs | 15 --- .../Options/IODataQueryOptionList.cs | 33 ----- .../Options/Nested/IODataOptionNested.cs | 23 ++++ .../Options/Nested/IODataQueryOptionNested.cs | 23 ---- .../Options/Nested/ODataOptionNested.cs | 85 +++++++++++++ .../Options/Nested/ODataQueryOptionNested.cs | 85 ------------- .../Options/ODataOptionKey.cs | 48 +++++++ .../Options/ODataOptionList.cs | 120 ++++++++++++++++++ .../Options/ODataQueryOptionKey.cs | 48 ------- .../Options/ODataQueryOptionList.cs | 120 ------------------ .../Resourses/IODataQueryResource.cs | 13 -- .../Visitors/VisitorExpression.cs | 32 ++--- 29 files changed, 390 insertions(+), 390 deletions(-) create mode 100644 src/OData.QueryBuilder/Builders/IODataQueryNestedBuilder.cs delete mode 100644 src/OData.QueryBuilder/Builders/Nested/IODataQueryNestedBuilder.cs rename src/OData.QueryBuilder/Builders/{Nested => }/ODataQueryNestedBuilder.cs (76%) create mode 100644 src/OData.QueryBuilder/Builders/Resourses/IODataQueryResource.cs rename src/OData.QueryBuilder/{ => Builders}/Resourses/ODataQueryResource.cs (60%) rename src/OData.QueryBuilder/Constants/{ODataQueryFunctions.cs => ODataFunctionNames.cs} (88%) rename src/OData.QueryBuilder/Constants/{ODataQueryOperators.cs => ODataOperatorNames.cs} (81%) rename src/OData.QueryBuilder/Constants/{ODataQueryOptions.cs => ODataOptionNames.cs} (91%) rename src/OData.QueryBuilder/Functions/{IODataQueryDateFunction.cs => IODataDateFunction.cs} (85%) create mode 100644 src/OData.QueryBuilder/Functions/IODataFunction.cs delete mode 100644 src/OData.QueryBuilder/Functions/IODataQueryFunction.cs rename src/OData.QueryBuilder/Functions/{IODataQueryStringFunction.cs => IODataStringFunction.cs} (93%) rename src/OData.QueryBuilder/Operators/{IODataQueryOperator.cs => IODataOperator.cs} (87%) create mode 100644 src/OData.QueryBuilder/Options/IODataOptionKey.cs create mode 100644 src/OData.QueryBuilder/Options/IODataOptionList.cs delete mode 100644 src/OData.QueryBuilder/Options/IODataQueryOptionKey.cs delete mode 100644 src/OData.QueryBuilder/Options/IODataQueryOptionList.cs create mode 100644 src/OData.QueryBuilder/Options/Nested/IODataOptionNested.cs delete mode 100644 src/OData.QueryBuilder/Options/Nested/IODataQueryOptionNested.cs create mode 100644 src/OData.QueryBuilder/Options/Nested/ODataOptionNested.cs delete mode 100644 src/OData.QueryBuilder/Options/Nested/ODataQueryOptionNested.cs create mode 100644 src/OData.QueryBuilder/Options/ODataOptionKey.cs create mode 100644 src/OData.QueryBuilder/Options/ODataOptionList.cs delete mode 100644 src/OData.QueryBuilder/Options/ODataQueryOptionKey.cs delete mode 100644 src/OData.QueryBuilder/Options/ODataQueryOptionList.cs delete mode 100644 src/OData.QueryBuilder/Resourses/IODataQueryResource.cs diff --git a/src/OData.QueryBuilder/Builders/IODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/IODataQueryBuilder.cs index 7276e4ef..4976ccb2 100644 --- a/src/OData.QueryBuilder/Builders/IODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/IODataQueryBuilder.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.Resourses; +using OData.QueryBuilder.Builders.Resourses; using System; using System.Linq.Expressions; diff --git a/src/OData.QueryBuilder/Builders/IODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/IODataQueryNestedBuilder.cs new file mode 100644 index 00000000..f5eb9543 --- /dev/null +++ b/src/OData.QueryBuilder/Builders/IODataQueryNestedBuilder.cs @@ -0,0 +1,11 @@ +using OData.QueryBuilder.Options.Nested; +using System; +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Builders +{ + public interface IODataQueryNestedBuilder + { + IODataOptionNested For(Expression> nestedEntityExpand); + } +} diff --git a/src/OData.QueryBuilder/Builders/Nested/IODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/Nested/IODataQueryNestedBuilder.cs deleted file mode 100644 index 7df6c54a..00000000 --- a/src/OData.QueryBuilder/Builders/Nested/IODataQueryNestedBuilder.cs +++ /dev/null @@ -1,11 +0,0 @@ -using OData.QueryBuilder.Options.Nested; -using System; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Builders.Nested -{ - public interface IODataQueryNestedBuilder - { - IODataQueryOptionNested For(Expression> nestedEntityExpand); - } -} diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index fe0bd555..2c400681 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -1,5 +1,5 @@ -using OData.QueryBuilder.Constants; -using OData.QueryBuilder.Resourses; +using OData.QueryBuilder.Builders.Resourses; +using OData.QueryBuilder.Constants; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; diff --git a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs similarity index 76% rename from src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs rename to src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs index d38e60b1..10584050 100644 --- a/src/OData.QueryBuilder/Builders/Nested/ODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs @@ -4,7 +4,7 @@ using System.Linq.Expressions; using System.Text; -namespace OData.QueryBuilder.Builders.Nested +namespace OData.QueryBuilder.Builders { public class ODataQueryNestedBuilder : IODataQueryNestedBuilder { @@ -16,7 +16,7 @@ public ODataQueryNestedBuilder() => public string Query => $"{_stringBuilder}({_odataQueryNested.Query})"; - public IODataQueryOptionNested For(Expression> nestedEntityExpand) + public IODataOptionNested For(Expression> nestedEntityExpand) { if (!string.IsNullOrEmpty(_odataQueryNested?.Query)) { @@ -33,9 +33,9 @@ public IODataQueryOptionNested For(Expression(); + _odataQueryNested = new ODataOptionNested(); - return _odataQueryNested as ODataQueryOptionNested; + return _odataQueryNested as ODataOptionNested; } } } diff --git a/src/OData.QueryBuilder/Builders/Resourses/IODataQueryResource.cs b/src/OData.QueryBuilder/Builders/Resourses/IODataQueryResource.cs new file mode 100644 index 00000000..ea42ed88 --- /dev/null +++ b/src/OData.QueryBuilder/Builders/Resourses/IODataQueryResource.cs @@ -0,0 +1,13 @@ +using OData.QueryBuilder.Options; + +namespace OData.QueryBuilder.Builders.Resourses +{ + public interface IODataQueryResource + { + IODataOptionKey ByKey(int key); + + IODataOptionKey ByKey(string key); + + IODataOptionList ByList(); + } +} diff --git a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs b/src/OData.QueryBuilder/Builders/Resourses/ODataQueryResource.cs similarity index 60% rename from src/OData.QueryBuilder/Resourses/ODataQueryResource.cs rename to src/OData.QueryBuilder/Builders/Resourses/ODataQueryResource.cs index e5822412..7853fdda 100644 --- a/src/OData.QueryBuilder/Resourses/ODataQueryResource.cs +++ b/src/OData.QueryBuilder/Builders/Resourses/ODataQueryResource.cs @@ -2,7 +2,7 @@ using OData.QueryBuilder.Options; using System.Text; -namespace OData.QueryBuilder.Resourses +namespace OData.QueryBuilder.Builders.Resourses { public class ODataQueryResource : IODataQueryResource { @@ -13,25 +13,25 @@ public ODataQueryResource(string resourceUrl) _stringBuilder = new StringBuilder(resourceUrl); } - public IODataQueryOptionKey ByKey(int key) + public IODataOptionKey ByKey(int key) { _stringBuilder.Append($"({key}){QuerySeparators.BeginString}"); - return new ODataQueryOptionKey(_stringBuilder); + return new ODataOptionKey(_stringBuilder); } - public IODataQueryOptionKey ByKey(string key) + public IODataOptionKey ByKey(string key) { _stringBuilder.Append($"('{key}'){QuerySeparators.BeginString}"); - return new ODataQueryOptionKey(_stringBuilder); + return new ODataOptionKey(_stringBuilder); } - public IODataQueryOptionList ByList() + public IODataOptionList ByList() { _stringBuilder.Append(QuerySeparators.BeginString); - return new ODataQueryOptionList(_stringBuilder); + return new ODataOptionList(_stringBuilder); } } } diff --git a/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs b/src/OData.QueryBuilder/Constants/ODataFunctionNames.cs similarity index 88% rename from src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs rename to src/OData.QueryBuilder/Constants/ODataFunctionNames.cs index 074fcf87..566f0d1d 100644 --- a/src/OData.QueryBuilder/Constants/ODataQueryFunctions.cs +++ b/src/OData.QueryBuilder/Constants/ODataFunctionNames.cs @@ -1,6 +1,6 @@ namespace OData.QueryBuilder.Constants { - internal struct ODataQueryFunctions + internal struct ODataFunctionNames { public const string Date = "date"; diff --git a/src/OData.QueryBuilder/Constants/ODataQueryOperators.cs b/src/OData.QueryBuilder/Constants/ODataOperatorNames.cs similarity index 81% rename from src/OData.QueryBuilder/Constants/ODataQueryOperators.cs rename to src/OData.QueryBuilder/Constants/ODataOperatorNames.cs index 6a956c71..2f6e9cd2 100644 --- a/src/OData.QueryBuilder/Constants/ODataQueryOperators.cs +++ b/src/OData.QueryBuilder/Constants/ODataOperatorNames.cs @@ -1,6 +1,6 @@ namespace OData.QueryBuilder.Constants { - internal struct ODataQueryOperators + internal struct ODataOperatorNames { public const string Any = "any"; diff --git a/src/OData.QueryBuilder/Constants/ODataQueryOptions.cs b/src/OData.QueryBuilder/Constants/ODataOptionNames.cs similarity index 91% rename from src/OData.QueryBuilder/Constants/ODataQueryOptions.cs rename to src/OData.QueryBuilder/Constants/ODataOptionNames.cs index cecb9da7..0236e404 100644 --- a/src/OData.QueryBuilder/Constants/ODataQueryOptions.cs +++ b/src/OData.QueryBuilder/Constants/ODataOptionNames.cs @@ -1,6 +1,6 @@ namespace OData.QueryBuilder.Constants { - internal struct ODataQueryOptions + internal struct ODataOptionNames { public const string Select = "$select"; diff --git a/src/OData.QueryBuilder/Functions/IODataQueryDateFunction.cs b/src/OData.QueryBuilder/Functions/IODataDateFunction.cs similarity index 85% rename from src/OData.QueryBuilder/Functions/IODataQueryDateFunction.cs rename to src/OData.QueryBuilder/Functions/IODataDateFunction.cs index ddb93f03..34e23efe 100644 --- a/src/OData.QueryBuilder/Functions/IODataQueryDateFunction.cs +++ b/src/OData.QueryBuilder/Functions/IODataDateFunction.cs @@ -2,7 +2,7 @@ namespace OData.QueryBuilder.Functions { - public interface IODataQueryDateFunction + public interface IODataDateFunction { /// /// http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_date diff --git a/src/OData.QueryBuilder/Functions/IODataFunction.cs b/src/OData.QueryBuilder/Functions/IODataFunction.cs new file mode 100644 index 00000000..87cd3a8c --- /dev/null +++ b/src/OData.QueryBuilder/Functions/IODataFunction.cs @@ -0,0 +1,6 @@ +namespace OData.QueryBuilder.Functions +{ + public interface IODataFunction : IODataStringFunction, IODataDateFunction, IConvertFunction + { + } +} diff --git a/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs b/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs deleted file mode 100644 index d99db72c..00000000 --- a/src/OData.QueryBuilder/Functions/IODataQueryFunction.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace OData.QueryBuilder.Functions -{ - public interface IODataQueryFunction : IODataQueryStringFunction, IODataQueryDateFunction, IConvertFunction - { - } -} diff --git a/src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs b/src/OData.QueryBuilder/Functions/IODataStringFunction.cs similarity index 93% rename from src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs rename to src/OData.QueryBuilder/Functions/IODataStringFunction.cs index f7105073..70286478 100644 --- a/src/OData.QueryBuilder/Functions/IODataQueryStringFunction.cs +++ b/src/OData.QueryBuilder/Functions/IODataStringFunction.cs @@ -1,6 +1,6 @@ namespace OData.QueryBuilder.Functions { - public interface IODataQueryStringFunction + public interface IODataStringFunction { bool SubstringOf(string value, string columnName); diff --git a/src/OData.QueryBuilder/Operators/IODataQueryOperator.cs b/src/OData.QueryBuilder/Operators/IODataOperator.cs similarity index 87% rename from src/OData.QueryBuilder/Operators/IODataQueryOperator.cs rename to src/OData.QueryBuilder/Operators/IODataOperator.cs index 1f4c09c4..36b34768 100644 --- a/src/OData.QueryBuilder/Operators/IODataQueryOperator.cs +++ b/src/OData.QueryBuilder/Operators/IODataOperator.cs @@ -3,7 +3,7 @@ namespace OData.QueryBuilder.Operators { - public interface IODataQueryOperator + public interface IODataOperator { bool In(T columnName, IEnumerable values); diff --git a/src/OData.QueryBuilder/Options/IODataOptionKey.cs b/src/OData.QueryBuilder/Options/IODataOptionKey.cs new file mode 100644 index 00000000..2982f411 --- /dev/null +++ b/src/OData.QueryBuilder/Options/IODataOptionKey.cs @@ -0,0 +1,15 @@ +using OData.QueryBuilder.Builders; +using System; +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Options +{ + public interface IODataOptionKey : IODataQuery + { + IODataOptionKey Expand(Expression> entityExpand); + + IODataOptionKey Expand(Action> entityExpandNested); + + IODataOptionKey Select(Expression> entitySelect); + } +} diff --git a/src/OData.QueryBuilder/Options/IODataOptionList.cs b/src/OData.QueryBuilder/Options/IODataOptionList.cs new file mode 100644 index 00000000..1d3dd995 --- /dev/null +++ b/src/OData.QueryBuilder/Options/IODataOptionList.cs @@ -0,0 +1,33 @@ +using OData.QueryBuilder.Builders; +using OData.QueryBuilder.Functions; +using OData.QueryBuilder.Operators; +using System; +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Options +{ + public interface IODataOptionList : IODataQuery + { + IODataOptionList Filter(Expression> entityFilter); + + IODataOptionList Filter(Expression> entityFilter); + + IODataOptionList Filter(Expression> entityFilter); + + IODataOptionList Expand(Expression> entityExpand); + + IODataOptionList Expand(Action> entityExpandNested); + + IODataOptionList Select(Expression> entitySelect); + + IODataOptionList OrderBy(Expression> entityOrderBy); + + IODataOptionList OrderByDescending(Expression> entityOrderByDescending); + + IODataOptionList Top(int number); + + IODataOptionList Skip(int number); + + IODataOptionList Count(bool value = true); + } +} \ No newline at end of file diff --git a/src/OData.QueryBuilder/Options/IODataQueryOptionKey.cs b/src/OData.QueryBuilder/Options/IODataQueryOptionKey.cs deleted file mode 100644 index 9326c747..00000000 --- a/src/OData.QueryBuilder/Options/IODataQueryOptionKey.cs +++ /dev/null @@ -1,15 +0,0 @@ -using OData.QueryBuilder.Builders.Nested; -using System; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Options -{ - public interface IODataQueryOptionKey : IODataQuery - { - IODataQueryOptionKey Expand(Expression> entityExpand); - - IODataQueryOptionKey Expand(Action> entityExpandNested); - - IODataQueryOptionKey Select(Expression> entitySelect); - } -} diff --git a/src/OData.QueryBuilder/Options/IODataQueryOptionList.cs b/src/OData.QueryBuilder/Options/IODataQueryOptionList.cs deleted file mode 100644 index ac4c3580..00000000 --- a/src/OData.QueryBuilder/Options/IODataQueryOptionList.cs +++ /dev/null @@ -1,33 +0,0 @@ -using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.Functions; -using OData.QueryBuilder.Operators; -using System; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Options -{ - public interface IODataQueryOptionList : IODataQuery - { - IODataQueryOptionList Filter(Expression> entityFilter); - - IODataQueryOptionList Filter(Expression> entityFilter); - - IODataQueryOptionList Filter(Expression> entityFilter); - - IODataQueryOptionList Expand(Expression> entityExpand); - - IODataQueryOptionList Expand(Action> entityExpandNested); - - IODataQueryOptionList Select(Expression> entitySelect); - - IODataQueryOptionList OrderBy(Expression> entityOrderBy); - - IODataQueryOptionList OrderByDescending(Expression> entityOrderByDescending); - - IODataQueryOptionList Top(int number); - - IODataQueryOptionList Skip(int number); - - IODataQueryOptionList Count(bool value = true); - } -} \ No newline at end of file diff --git a/src/OData.QueryBuilder/Options/Nested/IODataOptionNested.cs b/src/OData.QueryBuilder/Options/Nested/IODataOptionNested.cs new file mode 100644 index 00000000..76f30b78 --- /dev/null +++ b/src/OData.QueryBuilder/Options/Nested/IODataOptionNested.cs @@ -0,0 +1,23 @@ +using OData.QueryBuilder.Builders; +using System; +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Options.Nested +{ + public interface IODataOptionNested + { + IODataOptionNested Expand(Action> entityExpandNested); + + IODataOptionNested Expand(Expression> entityNestedExpand); + + IODataOptionNested Filter(Expression> entityNestedFilter); + + IODataOptionNested Select(Expression> entityNestedSelect); + + IODataOptionNested OrderBy(Expression> entityNestedOrderBy); + + IODataOptionNested OrderByDescending(Expression> entityNestedOrderByDescending); + + IODataOptionNested Top(int number); + } +} diff --git a/src/OData.QueryBuilder/Options/Nested/IODataQueryOptionNested.cs b/src/OData.QueryBuilder/Options/Nested/IODataQueryOptionNested.cs deleted file mode 100644 index 49cd02f9..00000000 --- a/src/OData.QueryBuilder/Options/Nested/IODataQueryOptionNested.cs +++ /dev/null @@ -1,23 +0,0 @@ -using OData.QueryBuilder.Builders.Nested; -using System; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Options.Nested -{ - public interface IODataQueryOptionNested - { - IODataQueryOptionNested Expand(Action> entityExpandNested); - - IODataQueryOptionNested Expand(Expression> entityNestedExpand); - - IODataQueryOptionNested Filter(Expression> entityNestedFilter); - - IODataQueryOptionNested Select(Expression> entityNestedSelect); - - IODataQueryOptionNested OrderBy(Expression> entityNestedOrderBy); - - IODataQueryOptionNested OrderByDescending(Expression> entityNestedOrderByDescending); - - IODataQueryOptionNested Top(int number); - } -} diff --git a/src/OData.QueryBuilder/Options/Nested/ODataOptionNested.cs b/src/OData.QueryBuilder/Options/Nested/ODataOptionNested.cs new file mode 100644 index 00000000..6029efa9 --- /dev/null +++ b/src/OData.QueryBuilder/Options/Nested/ODataOptionNested.cs @@ -0,0 +1,85 @@ +using OData.QueryBuilder.Builders; +using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Visitors; +using System; +using System.Linq.Expressions; +using System.Text; + +namespace OData.QueryBuilder.Options.Nested +{ + public class ODataOptionNested : ODataQueryNested, IODataOptionNested + { + public ODataOptionNested() + : base(new StringBuilder()) + { + } + + public IODataOptionNested Expand(Expression> entityNestedExpand) + { + var visitor = new VisitorExpression(entityNestedExpand.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataOptionNames.Expand}{QuerySeparators.EqualSignString}{query}{QuerySeparators.NestedString}"); + + return this; + } + + public IODataOptionNested Expand(Action> actionEntityExpandNested) + { + var builder = new ODataQueryNestedBuilder(); + + actionEntityExpandNested(builder); + + _stringBuilder.Append($"{ODataOptionNames.Expand}{QuerySeparators.EqualSignString}{builder.Query}{QuerySeparators.NestedString}"); + + return this; + } + + public IODataOptionNested Filter(Expression> entityNestedFilter) + { + var visitor = new VisitorExpression(entityNestedFilter.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataOptionNames.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.NestedString}"); + + return this; + } + + public IODataOptionNested OrderBy(Expression> entityNestedOrderBy) + { + var visitor = new VisitorExpression(entityNestedOrderBy.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataOptionNames.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Asc}{QuerySeparators.NestedString}"); + + return this; + } + + public IODataOptionNested OrderByDescending(Expression> entityNestedOrderByDescending) + { + var visitor = new VisitorExpression(entityNestedOrderByDescending.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataOptionNames.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Desc}{QuerySeparators.NestedString}"); + + return this; + } + + public IODataOptionNested Select(Expression> entityNestedSelect) + { + var visitor = new VisitorExpression(entityNestedSelect.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataOptionNames.Select}{QuerySeparators.EqualSignString}{query}{QuerySeparators.NestedString}"); + + return this; + } + + public IODataOptionNested Top(int value) + { + _stringBuilder.Append($"{ODataOptionNames.Top}{QuerySeparators.EqualSignString}{value}{QuerySeparators.NestedString}"); + + return this; + } + } +} diff --git a/src/OData.QueryBuilder/Options/Nested/ODataQueryOptionNested.cs b/src/OData.QueryBuilder/Options/Nested/ODataQueryOptionNested.cs deleted file mode 100644 index 31a9a14a..00000000 --- a/src/OData.QueryBuilder/Options/Nested/ODataQueryOptionNested.cs +++ /dev/null @@ -1,85 +0,0 @@ -using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.Constants; -using OData.QueryBuilder.Visitors; -using System; -using System.Linq.Expressions; -using System.Text; - -namespace OData.QueryBuilder.Options.Nested -{ - public class ODataQueryOptionNested : ODataQueryNested, IODataQueryOptionNested - { - public ODataQueryOptionNested() - : base(new StringBuilder()) - { - } - - public IODataQueryOptionNested Expand(Expression> entityNestedExpand) - { - var visitor = new VisitorExpression(entityNestedExpand.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryOptions.Expand}{QuerySeparators.EqualSignString}{query}{QuerySeparators.NestedString}"); - - return this; - } - - public IODataQueryOptionNested Expand(Action> actionEntityExpandNested) - { - var builder = new ODataQueryNestedBuilder(); - - actionEntityExpandNested(builder); - - _stringBuilder.Append($"{ODataQueryOptions.Expand}{QuerySeparators.EqualSignString}{builder.Query}{QuerySeparators.NestedString}"); - - return this; - } - - public IODataQueryOptionNested Filter(Expression> entityNestedFilter) - { - var visitor = new VisitorExpression(entityNestedFilter.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryOptions.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.NestedString}"); - - return this; - } - - public IODataQueryOptionNested OrderBy(Expression> entityNestedOrderBy) - { - var visitor = new VisitorExpression(entityNestedOrderBy.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryOptions.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Asc}{QuerySeparators.NestedString}"); - - return this; - } - - public IODataQueryOptionNested OrderByDescending(Expression> entityNestedOrderByDescending) - { - var visitor = new VisitorExpression(entityNestedOrderByDescending.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryOptions.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Desc}{QuerySeparators.NestedString}"); - - return this; - } - - public IODataQueryOptionNested Select(Expression> entityNestedSelect) - { - var visitor = new VisitorExpression(entityNestedSelect.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryOptions.Select}{QuerySeparators.EqualSignString}{query}{QuerySeparators.NestedString}"); - - return this; - } - - public IODataQueryOptionNested Top(int value) - { - _stringBuilder.Append($"{ODataQueryOptions.Top}{QuerySeparators.EqualSignString}{value}{QuerySeparators.NestedString}"); - - return this; - } - } -} diff --git a/src/OData.QueryBuilder/Options/ODataOptionKey.cs b/src/OData.QueryBuilder/Options/ODataOptionKey.cs new file mode 100644 index 00000000..718010d5 --- /dev/null +++ b/src/OData.QueryBuilder/Options/ODataOptionKey.cs @@ -0,0 +1,48 @@ +using OData.QueryBuilder.Builders; +using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Visitors; +using System; +using System.Linq.Expressions; +using System.Text; + +namespace OData.QueryBuilder.Options +{ + public class ODataOptionKey : ODataQuery, IODataOptionKey + { + public ODataOptionKey(StringBuilder stringBuilder) + : base(stringBuilder) + { + } + + public IODataOptionKey Expand(Expression> entityExpand) + { + var visitor = new VisitorExpression(entityExpand.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataOptionNames.Expand}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataOptionKey Expand(Action> actionEntityExpandNested) + { + var builder = new ODataQueryNestedBuilder(); + + actionEntityExpandNested(builder); + + _stringBuilder.Append($"{ODataOptionNames.Expand}{QuerySeparators.EqualSignString}{builder.Query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataOptionKey Select(Expression> entitySelect) + { + var visitor = new VisitorExpression(entitySelect.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataOptionNames.Select}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); + + return this; + } + } +} diff --git a/src/OData.QueryBuilder/Options/ODataOptionList.cs b/src/OData.QueryBuilder/Options/ODataOptionList.cs new file mode 100644 index 00000000..e670eff6 --- /dev/null +++ b/src/OData.QueryBuilder/Options/ODataOptionList.cs @@ -0,0 +1,120 @@ +using OData.QueryBuilder.Builders; +using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Functions; +using OData.QueryBuilder.Operators; +using OData.QueryBuilder.Visitors; +using System; +using System.Linq.Expressions; +using System.Text; + +namespace OData.QueryBuilder.Options +{ + public class ODataOptionList : ODataQuery, IODataOptionList + { + public ODataOptionList(StringBuilder stringBuilder) + : base(stringBuilder) + { + } + + public IODataOptionList Filter(Expression> entityFilter) + { + var visitor = new VisitorExpression(entityFilter.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataOptionNames.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataOptionList Filter(Expression> entityFilter) + { + var visitor = new VisitorExpression(entityFilter.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataOptionNames.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataOptionList Filter(Expression> entityFilter) + { + var visitor = new VisitorExpression(entityFilter.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataOptionNames.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataOptionList Expand(Expression> entityExpand) + { + var visitor = new VisitorExpression(entityExpand.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataOptionNames.Expand}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataOptionList Expand(Action> entityExpandNested) + { + var builder = new ODataQueryNestedBuilder(); + entityExpandNested(builder); + + _stringBuilder.Append($"{ODataOptionNames.Expand}{QuerySeparators.EqualSignString}{builder.Query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataOptionList Select(Expression> entitySelect) + { + var visitor = new VisitorExpression(entitySelect.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataOptionNames.Select}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); + + return this; + } + + public IODataOptionList OrderBy(Expression> entityOrderBy) + { + var visitor = new VisitorExpression(entityOrderBy.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataOptionNames.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Asc}{QuerySeparators.MainString}"); + + return this; + } + + public IODataOptionList OrderByDescending(Expression> entityOrderByDescending) + { + var visitor = new VisitorExpression(entityOrderByDescending.Body); + var query = visitor.ToString(); + + _stringBuilder.Append($"{ODataOptionNames.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Desc}{QuerySeparators.MainString}"); + + return this; + } + + public IODataOptionList Skip(int value) + { + _stringBuilder.Append($"{ODataOptionNames.Skip}{QuerySeparators.EqualSignString}{value}{QuerySeparators.MainString}"); + + return this; + } + + public IODataOptionList Top(int value) + { + _stringBuilder.Append($"{ODataOptionNames.Top}{QuerySeparators.EqualSignString}{value}{QuerySeparators.MainString}"); + + return this; + } + + public IODataOptionList Count(bool value = true) + { + _stringBuilder.Append($"{ODataOptionNames.Count}{QuerySeparators.EqualSignString}{value.ToString().ToLower()}{QuerySeparators.MainString}"); + + return this; + } + } +} diff --git a/src/OData.QueryBuilder/Options/ODataQueryOptionKey.cs b/src/OData.QueryBuilder/Options/ODataQueryOptionKey.cs deleted file mode 100644 index 9c4f4c49..00000000 --- a/src/OData.QueryBuilder/Options/ODataQueryOptionKey.cs +++ /dev/null @@ -1,48 +0,0 @@ -using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.Constants; -using OData.QueryBuilder.Visitors; -using System; -using System.Linq.Expressions; -using System.Text; - -namespace OData.QueryBuilder.Options -{ - public class ODataQueryOptionKey : ODataQuery, IODataQueryOptionKey - { - public ODataQueryOptionKey(StringBuilder stringBuilder) - : base(stringBuilder) - { - } - - public IODataQueryOptionKey Expand(Expression> entityExpand) - { - var visitor = new VisitorExpression(entityExpand.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryOptions.Expand}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); - - return this; - } - - public IODataQueryOptionKey Expand(Action> actionEntityExpandNested) - { - var builder = new ODataQueryNestedBuilder(); - - actionEntityExpandNested(builder); - - _stringBuilder.Append($"{ODataQueryOptions.Expand}{QuerySeparators.EqualSignString}{builder.Query}{QuerySeparators.MainString}"); - - return this; - } - - public IODataQueryOptionKey Select(Expression> entitySelect) - { - var visitor = new VisitorExpression(entitySelect.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryOptions.Select}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); - - return this; - } - } -} diff --git a/src/OData.QueryBuilder/Options/ODataQueryOptionList.cs b/src/OData.QueryBuilder/Options/ODataQueryOptionList.cs deleted file mode 100644 index 055ad122..00000000 --- a/src/OData.QueryBuilder/Options/ODataQueryOptionList.cs +++ /dev/null @@ -1,120 +0,0 @@ -using OData.QueryBuilder.Builders.Nested; -using OData.QueryBuilder.Constants; -using OData.QueryBuilder.Functions; -using OData.QueryBuilder.Operators; -using OData.QueryBuilder.Visitors; -using System; -using System.Linq.Expressions; -using System.Text; - -namespace OData.QueryBuilder.Options -{ - public class ODataQueryOptionList : ODataQuery, IODataQueryOptionList - { - public ODataQueryOptionList(StringBuilder stringBuilder) - : base(stringBuilder) - { - } - - public IODataQueryOptionList Filter(Expression> entityFilter) - { - var visitor = new VisitorExpression(entityFilter.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryOptions.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); - - return this; - } - - public IODataQueryOptionList Filter(Expression> entityFilter) - { - var visitor = new VisitorExpression(entityFilter.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryOptions.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); - - return this; - } - - public IODataQueryOptionList Filter(Expression> entityFilter) - { - var visitor = new VisitorExpression(entityFilter.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryOptions.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); - - return this; - } - - public IODataQueryOptionList Expand(Expression> entityExpand) - { - var visitor = new VisitorExpression(entityExpand.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryOptions.Expand}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); - - return this; - } - - public IODataQueryOptionList Expand(Action> entityExpandNested) - { - var builder = new ODataQueryNestedBuilder(); - entityExpandNested(builder); - - _stringBuilder.Append($"{ODataQueryOptions.Expand}{QuerySeparators.EqualSignString}{builder.Query}{QuerySeparators.MainString}"); - - return this; - } - - public IODataQueryOptionList Select(Expression> entitySelect) - { - var visitor = new VisitorExpression(entitySelect.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryOptions.Select}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); - - return this; - } - - public IODataQueryOptionList OrderBy(Expression> entityOrderBy) - { - var visitor = new VisitorExpression(entityOrderBy.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryOptions.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Asc}{QuerySeparators.MainString}"); - - return this; - } - - public IODataQueryOptionList OrderByDescending(Expression> entityOrderByDescending) - { - var visitor = new VisitorExpression(entityOrderByDescending.Body); - var query = visitor.ToString(); - - _stringBuilder.Append($"{ODataQueryOptions.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Desc}{QuerySeparators.MainString}"); - - return this; - } - - public IODataQueryOptionList Skip(int value) - { - _stringBuilder.Append($"{ODataQueryOptions.Skip}{QuerySeparators.EqualSignString}{value}{QuerySeparators.MainString}"); - - return this; - } - - public IODataQueryOptionList Top(int value) - { - _stringBuilder.Append($"{ODataQueryOptions.Top}{QuerySeparators.EqualSignString}{value}{QuerySeparators.MainString}"); - - return this; - } - - public IODataQueryOptionList Count(bool value = true) - { - _stringBuilder.Append($"{ODataQueryOptions.Count}{QuerySeparators.EqualSignString}{value.ToString().ToLower()}{QuerySeparators.MainString}"); - - return this; - } - } -} diff --git a/src/OData.QueryBuilder/Resourses/IODataQueryResource.cs b/src/OData.QueryBuilder/Resourses/IODataQueryResource.cs deleted file mode 100644 index dc6b1184..00000000 --- a/src/OData.QueryBuilder/Resourses/IODataQueryResource.cs +++ /dev/null @@ -1,13 +0,0 @@ -using OData.QueryBuilder.Options; - -namespace OData.QueryBuilder.Resourses -{ - public interface IODataQueryResource - { - IODataQueryOptionKey ByKey(int key); - - IODataQueryOptionKey ByKey(string key); - - IODataQueryOptionList ByList(); - } -} diff --git a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs index 04938c0e..aca8bee4 100644 --- a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs +++ b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs @@ -55,44 +55,44 @@ protected string VisitMethodCallExpression(MethodCallExpression methodCallExpres { switch (methodCallExpression.Method.Name) { - case nameof(IODataQueryOperator.In): + case nameof(IODataOperator.In): var in0 = VisitExpression(methodCallExpression.Arguments[0]); var in1 = VisitExpression(methodCallExpression.Arguments[1]) ?? throw new ArgumentException("Enumeration is empty or null"); - return $"{in0} {ODataQueryOperators.In} ({in1})"; - case nameof(IODataQueryOperator.All): + return $"{in0} {ODataOperatorNames.In} ({in1})"; + case nameof(IODataOperator.All): var all0 = VisitExpression(methodCallExpression.Arguments[0]); var all1 = VisitExpression(methodCallExpression.Arguments[1]); - return $"{all0}/{ODataQueryOperators.All}({all1})"; - case nameof(IODataQueryOperator.Any): + return $"{all0}/{ODataOperatorNames.All}({all1})"; + case nameof(IODataOperator.Any): var any0 = VisitExpression(methodCallExpression.Arguments[0]); var any1 = VisitExpression(methodCallExpression.Arguments[1]); - return $"{any0}/{ODataQueryOperators.Any}({any1})"; - case nameof(IODataQueryFunction.Date): + return $"{any0}/{ODataOperatorNames.Any}({any1})"; + case nameof(IODataFunction.Date): var date0 = VisitExpression(methodCallExpression.Arguments[0]); - return $"{ODataQueryFunctions.Date}({date0})"; - case nameof(IODataQueryFunction.SubstringOf): + return $"{ODataFunctionNames.Date}({date0})"; + case nameof(IODataFunction.SubstringOf): var substringOf0 = GetValueOfExpression(methodCallExpression.Arguments[0]); var substringOf1 = VisitExpression(methodCallExpression.Arguments[1]); - return $"{ODataQueryFunctions.SubstringOf}('{substringOf0}',{substringOf1})"; - case nameof(IODataQueryFunction.Contains): + return $"{ODataFunctionNames.SubstringOf}('{substringOf0}',{substringOf1})"; + case nameof(IODataFunction.Contains): var contains0 = VisitExpression(methodCallExpression.Arguments[0]); var contains1 = GetValueOfExpression(methodCallExpression.Arguments[1]); - return $"{ODataQueryFunctions.Contains}({contains0},'{contains1}')"; - case nameof(IODataQueryStringFunction.ToUpper): + return $"{ODataFunctionNames.Contains}({contains0},'{contains1}')"; + case nameof(IODataStringFunction.ToUpper): var toUpper0 = VisitExpression(methodCallExpression.Arguments[0]); - return $"{ODataQueryFunctions.ToUpper}({toUpper0})"; - case nameof(IODataQueryStringFunction.ToLower): + return $"{ODataFunctionNames.ToUpper}({toUpper0})"; + case nameof(IODataStringFunction.ToLower): var toLower0 = VisitExpression(methodCallExpression.Arguments[0]); - return $"{ODataQueryFunctions.ToLower}({toLower0})"; + return $"{ODataFunctionNames.ToLower}({toLower0})"; case nameof(IConvertFunction.ConvertEnumToString): return $"'{GetValueOfExpression(methodCallExpression.Arguments[0])}'"; case nameof(IConvertFunction.ConvertDateTimeToString): From d6128c6cdf81172eaacb59683beb0c26a8475b6f Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Tue, 23 Jun 2020 22:50:22 +0300 Subject: [PATCH 30/76] #ZEX#virtual --- .../Visitors/VisitorExpression.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs index aca8bee4..6c2e35ca 100644 --- a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs +++ b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs @@ -13,7 +13,7 @@ internal class VisitorExpression public VisitorExpression(Expression expression) => _expression = expression; - protected string VisitExpression(Expression expression) => expression switch + protected virtual string VisitExpression(Expression expression) => expression switch { BinaryExpression binaryExpression => VisitBinaryExpression(binaryExpression), MemberExpression memberExpression => VisitMemberExpression(memberExpression), @@ -25,7 +25,7 @@ internal class VisitorExpression _ => default, }; - protected string VisitBinaryExpression(BinaryExpression binaryExpression) + protected virtual string VisitBinaryExpression(BinaryExpression binaryExpression) { var left = VisitExpression(binaryExpression.Left); var right = VisitExpression(binaryExpression.Right); @@ -43,15 +43,15 @@ protected string VisitBinaryExpression(BinaryExpression binaryExpression) return $"{left} {binaryExpression.NodeType.ToODataQueryOperator()} {right}"; } - protected string VisitMemberExpression(MemberExpression memberExpression) => + protected virtual string VisitMemberExpression(MemberExpression memberExpression) => IsResourceOfMemberExpression(memberExpression) ? CreateResourcePath(memberExpression) : ReflectionExtensions.ConvertToString(GetValueOfMemberExpression(memberExpression)); - protected string VisitConstantExpression(ConstantExpression constantExpression) => + protected virtual string VisitConstantExpression(ConstantExpression constantExpression) => constantExpression.Value == default ? "null" : ReflectionExtensions.ConvertToString(constantExpression.Value); - protected string VisitMethodCallExpression(MethodCallExpression methodCallExpression) + protected virtual string VisitMethodCallExpression(MethodCallExpression methodCallExpression) { switch (methodCallExpression.Method.Name) { @@ -110,7 +110,7 @@ protected string VisitMethodCallExpression(MethodCallExpression methodCallExpres } } - protected string VisitNewExpression(NewExpression newExpression) + protected virtual string VisitNewExpression(NewExpression newExpression) { if (newExpression.Members == default) { @@ -139,7 +139,7 @@ protected string VisitNewExpression(NewExpression newExpression) return string.Join(QuerySeparators.CommaString, names); } - protected string VisitUnaryExpression(UnaryExpression unaryExpression) + protected virtual string VisitUnaryExpression(UnaryExpression unaryExpression) { var odataOperator = unaryExpression.NodeType.ToODataQueryOperator(); var whitespace = odataOperator != default ? " " : default; @@ -147,7 +147,7 @@ protected string VisitUnaryExpression(UnaryExpression unaryExpression) return $"{odataOperator}{whitespace}{VisitExpression(unaryExpression.Operand)}"; } - protected string VisitLambdaExpression(LambdaExpression lambdaExpression) + protected virtual string VisitLambdaExpression(LambdaExpression lambdaExpression) { var tag = lambdaExpression.Parameters[0]?.Name; var filter = VisitExpression(lambdaExpression.Body); @@ -155,31 +155,31 @@ protected string VisitLambdaExpression(LambdaExpression lambdaExpression) return $"{tag}:{tag}/{filter}"; } - private object GetValueOfExpression(Expression expression) => expression switch + protected object GetValueOfExpression(Expression expression) => expression switch { MemberExpression memberExpression => GetValueOfMemberExpression(memberExpression), ConstantExpression constantExpression => GetValueOfConstantExpression(constantExpression), _ => default, }; - private object GetValueOfConstantExpression(ConstantExpression constantExpression) => + protected object GetValueOfConstantExpression(ConstantExpression constantExpression) => constantExpression.Value; - private object GetValueOfMemberExpression(MemberExpression expression) => expression.Expression switch + protected object GetValueOfMemberExpression(MemberExpression expression) => expression.Expression switch { ConstantExpression constantExpression => expression.Member.GetValue(constantExpression.Value), MemberExpression memberExpression => expression.Member.GetValue(GetValueOfMemberExpression(memberExpression)), _ => expression.Member.GetValue(), }; - private bool IsResourceOfMemberExpression(MemberExpression memberExpression) => memberExpression.Expression switch + protected bool IsResourceOfMemberExpression(MemberExpression memberExpression) => memberExpression.Expression switch { ParameterExpression pe => pe.Type.GetProperty(memberExpression.Member.Name, memberExpression.Type) != default, MemberExpression me => IsResourceOfMemberExpression(me), _ => false, }; - private string CreateResourcePath(MemberExpression memberExpression) + protected string CreateResourcePath(MemberExpression memberExpression) { var name = VisitExpression(memberExpression.Expression); From 551049a6b8c7a692e613efc63a81b55a3dd2b542 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Tue, 23 Jun 2020 23:03:13 +0300 Subject: [PATCH 31/76] #ZEX#review --- .../Builders/IODataQueryNestedBuilder.cs | 2 +- src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs | 2 +- .../Builders/ODataQueryNestedBuilder.cs | 2 +- .../Builders/Resourses/IODataQueryResource.cs | 2 +- .../Builders/Resourses/ODataQueryResource.cs | 4 ++-- .../{ => Conventions}/Constants/ODataFunctionNames.cs | 2 +- .../{ => Conventions}/Constants/ODataOperatorNames.cs | 2 +- .../{ => Conventions}/Constants/ODataOptionNames.cs | 2 +- .../{ => Conventions}/Constants/QuerySeparators.cs | 2 +- .../{ => Conventions}/Constants/QuerySorts.cs | 2 +- .../{ => Conventions}/Functions/IConvertFunction.cs | 2 +- .../{ => Conventions}/Functions/IODataDateFunction.cs | 2 +- .../{ => Conventions}/Functions/IODataFunction.cs | 2 +- .../{ => Conventions}/Functions/IODataStringFunction.cs | 2 +- .../{ => Conventions}/Operators/IODataOperator.cs | 2 +- .../{ => Conventions}/Options/IODataOptionKey.cs | 2 +- .../{ => Conventions}/Options/IODataOptionList.cs | 6 +++--- .../Options/Nested/IODataOptionNested.cs | 2 +- .../{ => Conventions}/Options/Nested/ODataOptionNested.cs | 4 ++-- .../{ => Conventions}/Options/ODataOptionKey.cs | 4 ++-- .../{ => Conventions}/Options/ODataOptionList.cs | 8 ++++---- src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs | 2 +- src/OData.QueryBuilder/ODataQuery.cs | 2 +- src/OData.QueryBuilder/ODataQueryNested.cs | 2 +- src/OData.QueryBuilder/Visitors/VisitorExpression.cs | 6 +++--- 25 files changed, 35 insertions(+), 35 deletions(-) rename src/OData.QueryBuilder/{ => Conventions}/Constants/ODataFunctionNames.cs (85%) rename src/OData.QueryBuilder/{ => Conventions}/Constants/ODataOperatorNames.cs (76%) rename src/OData.QueryBuilder/{ => Conventions}/Constants/ODataOptionNames.cs (87%) rename src/OData.QueryBuilder/{ => Conventions}/Constants/QuerySeparators.cs (91%) rename src/OData.QueryBuilder/{ => Conventions}/Constants/QuerySorts.cs (70%) rename src/OData.QueryBuilder/{ => Conventions}/Functions/IConvertFunction.cs (85%) rename src/OData.QueryBuilder/{ => Conventions}/Functions/IODataDateFunction.cs (84%) rename src/OData.QueryBuilder/{ => Conventions}/Functions/IODataFunction.cs (67%) rename src/OData.QueryBuilder/{ => Conventions}/Functions/IODataStringFunction.cs (93%) rename src/OData.QueryBuilder/{ => Conventions}/Operators/IODataOperator.cs (84%) rename src/OData.QueryBuilder/{ => Conventions}/Options/IODataOptionKey.cs (90%) rename src/OData.QueryBuilder/{ => Conventions}/Options/IODataOptionList.cs (88%) rename src/OData.QueryBuilder/{ => Conventions}/Options/Nested/IODataOptionNested.cs (93%) rename src/OData.QueryBuilder/{ => Conventions}/Options/Nested/ODataOptionNested.cs (96%) rename src/OData.QueryBuilder/{ => Conventions}/Options/ODataOptionKey.cs (94%) rename src/OData.QueryBuilder/{ => Conventions}/Options/ODataOptionList.cs (95%) diff --git a/src/OData.QueryBuilder/Builders/IODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/IODataQueryNestedBuilder.cs index f5eb9543..784d6d8e 100644 --- a/src/OData.QueryBuilder/Builders/IODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/IODataQueryNestedBuilder.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.Options.Nested; +using OData.QueryBuilder.Conventions.Options.Nested; using System; using System.Linq.Expressions; diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index 2c400681..5afc6606 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -1,5 +1,5 @@ using OData.QueryBuilder.Builders.Resourses; -using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Conventions.Constants; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; diff --git a/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs index 10584050..82d87261 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.Options.Nested; +using OData.QueryBuilder.Conventions.Options.Nested; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; diff --git a/src/OData.QueryBuilder/Builders/Resourses/IODataQueryResource.cs b/src/OData.QueryBuilder/Builders/Resourses/IODataQueryResource.cs index ea42ed88..f565a6cc 100644 --- a/src/OData.QueryBuilder/Builders/Resourses/IODataQueryResource.cs +++ b/src/OData.QueryBuilder/Builders/Resourses/IODataQueryResource.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.Options; +using OData.QueryBuilder.Conventions.Options; namespace OData.QueryBuilder.Builders.Resourses { diff --git a/src/OData.QueryBuilder/Builders/Resourses/ODataQueryResource.cs b/src/OData.QueryBuilder/Builders/Resourses/ODataQueryResource.cs index 7853fdda..067f16c8 100644 --- a/src/OData.QueryBuilder/Builders/Resourses/ODataQueryResource.cs +++ b/src/OData.QueryBuilder/Builders/Resourses/ODataQueryResource.cs @@ -1,5 +1,5 @@ -using OData.QueryBuilder.Constants; -using OData.QueryBuilder.Options; +using OData.QueryBuilder.Conventions.Constants; +using OData.QueryBuilder.Conventions.Options; using System.Text; namespace OData.QueryBuilder.Builders.Resourses diff --git a/src/OData.QueryBuilder/Constants/ODataFunctionNames.cs b/src/OData.QueryBuilder/Conventions/Constants/ODataFunctionNames.cs similarity index 85% rename from src/OData.QueryBuilder/Constants/ODataFunctionNames.cs rename to src/OData.QueryBuilder/Conventions/Constants/ODataFunctionNames.cs index 566f0d1d..7d8698c3 100644 --- a/src/OData.QueryBuilder/Constants/ODataFunctionNames.cs +++ b/src/OData.QueryBuilder/Conventions/Constants/ODataFunctionNames.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.Constants +namespace OData.QueryBuilder.Conventions.Constants { internal struct ODataFunctionNames { diff --git a/src/OData.QueryBuilder/Constants/ODataOperatorNames.cs b/src/OData.QueryBuilder/Conventions/Constants/ODataOperatorNames.cs similarity index 76% rename from src/OData.QueryBuilder/Constants/ODataOperatorNames.cs rename to src/OData.QueryBuilder/Conventions/Constants/ODataOperatorNames.cs index 2f6e9cd2..7d4a43f0 100644 --- a/src/OData.QueryBuilder/Constants/ODataOperatorNames.cs +++ b/src/OData.QueryBuilder/Conventions/Constants/ODataOperatorNames.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.Constants +namespace OData.QueryBuilder.Conventions.Constants { internal struct ODataOperatorNames { diff --git a/src/OData.QueryBuilder/Constants/ODataOptionNames.cs b/src/OData.QueryBuilder/Conventions/Constants/ODataOptionNames.cs similarity index 87% rename from src/OData.QueryBuilder/Constants/ODataOptionNames.cs rename to src/OData.QueryBuilder/Conventions/Constants/ODataOptionNames.cs index 0236e404..340d37ef 100644 --- a/src/OData.QueryBuilder/Constants/ODataOptionNames.cs +++ b/src/OData.QueryBuilder/Conventions/Constants/ODataOptionNames.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.Constants +namespace OData.QueryBuilder.Conventions.Constants { internal struct ODataOptionNames { diff --git a/src/OData.QueryBuilder/Constants/QuerySeparators.cs b/src/OData.QueryBuilder/Conventions/Constants/QuerySeparators.cs similarity index 91% rename from src/OData.QueryBuilder/Constants/QuerySeparators.cs rename to src/OData.QueryBuilder/Conventions/Constants/QuerySeparators.cs index f2d30894..b8151ccc 100644 --- a/src/OData.QueryBuilder/Constants/QuerySeparators.cs +++ b/src/OData.QueryBuilder/Conventions/Constants/QuerySeparators.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.Constants +namespace OData.QueryBuilder.Conventions.Constants { internal struct QuerySeparators { diff --git a/src/OData.QueryBuilder/Constants/QuerySorts.cs b/src/OData.QueryBuilder/Conventions/Constants/QuerySorts.cs similarity index 70% rename from src/OData.QueryBuilder/Constants/QuerySorts.cs rename to src/OData.QueryBuilder/Conventions/Constants/QuerySorts.cs index 49632288..8774c254 100644 --- a/src/OData.QueryBuilder/Constants/QuerySorts.cs +++ b/src/OData.QueryBuilder/Conventions/Constants/QuerySorts.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.Constants +namespace OData.QueryBuilder.Conventions.Constants { internal struct QuerySorts { diff --git a/src/OData.QueryBuilder/Functions/IConvertFunction.cs b/src/OData.QueryBuilder/Conventions/Functions/IConvertFunction.cs similarity index 85% rename from src/OData.QueryBuilder/Functions/IConvertFunction.cs rename to src/OData.QueryBuilder/Conventions/Functions/IConvertFunction.cs index 8fd1bea0..3e3c43e9 100644 --- a/src/OData.QueryBuilder/Functions/IConvertFunction.cs +++ b/src/OData.QueryBuilder/Conventions/Functions/IConvertFunction.cs @@ -1,6 +1,6 @@ using System; -namespace OData.QueryBuilder.Functions +namespace OData.QueryBuilder.Conventions.Functions { public interface IConvertFunction { diff --git a/src/OData.QueryBuilder/Functions/IODataDateFunction.cs b/src/OData.QueryBuilder/Conventions/Functions/IODataDateFunction.cs similarity index 84% rename from src/OData.QueryBuilder/Functions/IODataDateFunction.cs rename to src/OData.QueryBuilder/Conventions/Functions/IODataDateFunction.cs index 34e23efe..423137e9 100644 --- a/src/OData.QueryBuilder/Functions/IODataDateFunction.cs +++ b/src/OData.QueryBuilder/Conventions/Functions/IODataDateFunction.cs @@ -1,6 +1,6 @@ using System; -namespace OData.QueryBuilder.Functions +namespace OData.QueryBuilder.Conventions.Functions { public interface IODataDateFunction { diff --git a/src/OData.QueryBuilder/Functions/IODataFunction.cs b/src/OData.QueryBuilder/Conventions/Functions/IODataFunction.cs similarity index 67% rename from src/OData.QueryBuilder/Functions/IODataFunction.cs rename to src/OData.QueryBuilder/Conventions/Functions/IODataFunction.cs index 87cd3a8c..892a4167 100644 --- a/src/OData.QueryBuilder/Functions/IODataFunction.cs +++ b/src/OData.QueryBuilder/Conventions/Functions/IODataFunction.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.Functions +namespace OData.QueryBuilder.Conventions.Functions { public interface IODataFunction : IODataStringFunction, IODataDateFunction, IConvertFunction { diff --git a/src/OData.QueryBuilder/Functions/IODataStringFunction.cs b/src/OData.QueryBuilder/Conventions/Functions/IODataStringFunction.cs similarity index 93% rename from src/OData.QueryBuilder/Functions/IODataStringFunction.cs rename to src/OData.QueryBuilder/Conventions/Functions/IODataStringFunction.cs index 70286478..37d31370 100644 --- a/src/OData.QueryBuilder/Functions/IODataStringFunction.cs +++ b/src/OData.QueryBuilder/Conventions/Functions/IODataStringFunction.cs @@ -1,4 +1,4 @@ -namespace OData.QueryBuilder.Functions +namespace OData.QueryBuilder.Conventions.Functions { public interface IODataStringFunction { diff --git a/src/OData.QueryBuilder/Operators/IODataOperator.cs b/src/OData.QueryBuilder/Conventions/Operators/IODataOperator.cs similarity index 84% rename from src/OData.QueryBuilder/Operators/IODataOperator.cs rename to src/OData.QueryBuilder/Conventions/Operators/IODataOperator.cs index 36b34768..145cef4a 100644 --- a/src/OData.QueryBuilder/Operators/IODataOperator.cs +++ b/src/OData.QueryBuilder/Conventions/Operators/IODataOperator.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace OData.QueryBuilder.Operators +namespace OData.QueryBuilder.Conventions.Operators { public interface IODataOperator { diff --git a/src/OData.QueryBuilder/Options/IODataOptionKey.cs b/src/OData.QueryBuilder/Conventions/Options/IODataOptionKey.cs similarity index 90% rename from src/OData.QueryBuilder/Options/IODataOptionKey.cs rename to src/OData.QueryBuilder/Conventions/Options/IODataOptionKey.cs index 2982f411..78c48980 100644 --- a/src/OData.QueryBuilder/Options/IODataOptionKey.cs +++ b/src/OData.QueryBuilder/Conventions/Options/IODataOptionKey.cs @@ -2,7 +2,7 @@ using System; using System.Linq.Expressions; -namespace OData.QueryBuilder.Options +namespace OData.QueryBuilder.Conventions.Options { public interface IODataOptionKey : IODataQuery { diff --git a/src/OData.QueryBuilder/Options/IODataOptionList.cs b/src/OData.QueryBuilder/Conventions/Options/IODataOptionList.cs similarity index 88% rename from src/OData.QueryBuilder/Options/IODataOptionList.cs rename to src/OData.QueryBuilder/Conventions/Options/IODataOptionList.cs index 1d3dd995..6fe78bf3 100644 --- a/src/OData.QueryBuilder/Options/IODataOptionList.cs +++ b/src/OData.QueryBuilder/Conventions/Options/IODataOptionList.cs @@ -1,10 +1,10 @@ using OData.QueryBuilder.Builders; -using OData.QueryBuilder.Functions; -using OData.QueryBuilder.Operators; +using OData.QueryBuilder.Conventions.Functions; +using OData.QueryBuilder.Conventions.Operators; using System; using System.Linq.Expressions; -namespace OData.QueryBuilder.Options +namespace OData.QueryBuilder.Conventions.Options { public interface IODataOptionList : IODataQuery { diff --git a/src/OData.QueryBuilder/Options/Nested/IODataOptionNested.cs b/src/OData.QueryBuilder/Conventions/Options/Nested/IODataOptionNested.cs similarity index 93% rename from src/OData.QueryBuilder/Options/Nested/IODataOptionNested.cs rename to src/OData.QueryBuilder/Conventions/Options/Nested/IODataOptionNested.cs index 76f30b78..eef885d5 100644 --- a/src/OData.QueryBuilder/Options/Nested/IODataOptionNested.cs +++ b/src/OData.QueryBuilder/Conventions/Options/Nested/IODataOptionNested.cs @@ -2,7 +2,7 @@ using System; using System.Linq.Expressions; -namespace OData.QueryBuilder.Options.Nested +namespace OData.QueryBuilder.Conventions.Options.Nested { public interface IODataOptionNested { diff --git a/src/OData.QueryBuilder/Options/Nested/ODataOptionNested.cs b/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs similarity index 96% rename from src/OData.QueryBuilder/Options/Nested/ODataOptionNested.cs rename to src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs index 6029efa9..86c728ad 100644 --- a/src/OData.QueryBuilder/Options/Nested/ODataOptionNested.cs +++ b/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs @@ -1,11 +1,11 @@ using OData.QueryBuilder.Builders; -using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Conventions.Constants; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; using System.Text; -namespace OData.QueryBuilder.Options.Nested +namespace OData.QueryBuilder.Conventions.Options.Nested { public class ODataOptionNested : ODataQueryNested, IODataOptionNested { diff --git a/src/OData.QueryBuilder/Options/ODataOptionKey.cs b/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs similarity index 94% rename from src/OData.QueryBuilder/Options/ODataOptionKey.cs rename to src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs index 718010d5..f77e884c 100644 --- a/src/OData.QueryBuilder/Options/ODataOptionKey.cs +++ b/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs @@ -1,11 +1,11 @@ using OData.QueryBuilder.Builders; -using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Conventions.Constants; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; using System.Text; -namespace OData.QueryBuilder.Options +namespace OData.QueryBuilder.Conventions.Options { public class ODataOptionKey : ODataQuery, IODataOptionKey { diff --git a/src/OData.QueryBuilder/Options/ODataOptionList.cs b/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs similarity index 95% rename from src/OData.QueryBuilder/Options/ODataOptionList.cs rename to src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs index e670eff6..7ac33210 100644 --- a/src/OData.QueryBuilder/Options/ODataOptionList.cs +++ b/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs @@ -1,13 +1,13 @@ using OData.QueryBuilder.Builders; -using OData.QueryBuilder.Constants; -using OData.QueryBuilder.Functions; -using OData.QueryBuilder.Operators; +using OData.QueryBuilder.Conventions.Constants; +using OData.QueryBuilder.Conventions.Functions; +using OData.QueryBuilder.Conventions.Operators; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; using System.Text; -namespace OData.QueryBuilder.Options +namespace OData.QueryBuilder.Conventions.Options { public class ODataOptionList : ODataQuery, IODataOptionList { diff --git a/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs b/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs index d72a213d..5da5afa4 100644 --- a/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Conventions.Constants; using System; using System.Collections.Generic; using System.Reflection; diff --git a/src/OData.QueryBuilder/ODataQuery.cs b/src/OData.QueryBuilder/ODataQuery.cs index 87fab452..77c373d4 100644 --- a/src/OData.QueryBuilder/ODataQuery.cs +++ b/src/OData.QueryBuilder/ODataQuery.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Conventions.Constants; using System; using System.Collections.Generic; using System.Text; diff --git a/src/OData.QueryBuilder/ODataQueryNested.cs b/src/OData.QueryBuilder/ODataQueryNested.cs index 463dfb36..e8a7b9f4 100644 --- a/src/OData.QueryBuilder/ODataQueryNested.cs +++ b/src/OData.QueryBuilder/ODataQueryNested.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Conventions.Constants; using System.Text; namespace OData.QueryBuilder diff --git a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs index 6c2e35ca..b9b2cdae 100644 --- a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs +++ b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs @@ -1,7 +1,7 @@ -using OData.QueryBuilder.Constants; +using OData.QueryBuilder.Conventions.Constants; +using OData.QueryBuilder.Conventions.Functions; +using OData.QueryBuilder.Conventions.Operators; using OData.QueryBuilder.Extensions; -using OData.QueryBuilder.Functions; -using OData.QueryBuilder.Operators; using System; using System.Linq.Expressions; From 95f409d79502d696d82569c7551de25603fec2f6 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Tue, 23 Jun 2020 23:08:57 +0300 Subject: [PATCH 32/76] #ZEXSM#review --- src/OData.QueryBuilder/Builders/IODataQueryBuilder.cs | 4 ++-- src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs | 8 ++++---- .../Options/IODataOption.cs} | 6 ++---- .../Options/ODataOption.cs} | 7 +++---- 4 files changed, 11 insertions(+), 14 deletions(-) rename src/OData.QueryBuilder/{Builders/Resourses/IODataQueryResource.cs => Conventions/Options/IODataOption.cs} (52%) rename src/OData.QueryBuilder/{Builders/Resourses/ODataQueryResource.cs => Conventions/Options/ODataOption.cs} (79%) diff --git a/src/OData.QueryBuilder/Builders/IODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/IODataQueryBuilder.cs index 4976ccb2..44617473 100644 --- a/src/OData.QueryBuilder/Builders/IODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/IODataQueryBuilder.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.Builders.Resourses; +using OData.QueryBuilder.Conventions.Options; using System; using System.Linq.Expressions; @@ -6,6 +6,6 @@ namespace OData.QueryBuilder.Builders { public interface IODataQueryBuilder { - IODataQueryResource For(Expression> entityResource); + IODataOption For(Expression> entityResource); } } \ No newline at end of file diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index 5afc6606..666c3501 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -1,5 +1,5 @@ -using OData.QueryBuilder.Builders.Resourses; -using OData.QueryBuilder.Conventions.Constants; +using OData.QueryBuilder.Conventions.Constants; +using OData.QueryBuilder.Conventions.Options; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; @@ -20,12 +20,12 @@ public ODataQueryBuilder(string baseUrl) _baseUrl = $"{baseUrl.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"; } - public IODataQueryResource For(Expression> entityResource) + public IODataOption For(Expression> entityResource) { var visitor = new VisitorExpression(entityResource.Body); var query = visitor.ToString(); - return new ODataQueryResource($"{_baseUrl}{query}"); + return new ODataOption($"{_baseUrl}{query}"); } } } \ No newline at end of file diff --git a/src/OData.QueryBuilder/Builders/Resourses/IODataQueryResource.cs b/src/OData.QueryBuilder/Conventions/Options/IODataOption.cs similarity index 52% rename from src/OData.QueryBuilder/Builders/Resourses/IODataQueryResource.cs rename to src/OData.QueryBuilder/Conventions/Options/IODataOption.cs index f565a6cc..04b938c5 100644 --- a/src/OData.QueryBuilder/Builders/Resourses/IODataQueryResource.cs +++ b/src/OData.QueryBuilder/Conventions/Options/IODataOption.cs @@ -1,8 +1,6 @@ -using OData.QueryBuilder.Conventions.Options; - -namespace OData.QueryBuilder.Builders.Resourses +namespace OData.QueryBuilder.Conventions.Options { - public interface IODataQueryResource + public interface IODataOption { IODataOptionKey ByKey(int key); diff --git a/src/OData.QueryBuilder/Builders/Resourses/ODataQueryResource.cs b/src/OData.QueryBuilder/Conventions/Options/ODataOption.cs similarity index 79% rename from src/OData.QueryBuilder/Builders/Resourses/ODataQueryResource.cs rename to src/OData.QueryBuilder/Conventions/Options/ODataOption.cs index 067f16c8..4c30237e 100644 --- a/src/OData.QueryBuilder/Builders/Resourses/ODataQueryResource.cs +++ b/src/OData.QueryBuilder/Conventions/Options/ODataOption.cs @@ -1,14 +1,13 @@ using OData.QueryBuilder.Conventions.Constants; -using OData.QueryBuilder.Conventions.Options; using System.Text; -namespace OData.QueryBuilder.Builders.Resourses +namespace OData.QueryBuilder.Conventions.Options { - public class ODataQueryResource : IODataQueryResource + public class ODataOption : IODataOption { private readonly StringBuilder _stringBuilder; - public ODataQueryResource(string resourceUrl) + public ODataOption(string resourceUrl) { _stringBuilder = new StringBuilder(resourceUrl); } From b00875aa5733c745311a4777a154c55740fef6dd Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Tue, 23 Jun 2020 23:31:25 +0300 Subject: [PATCH 33/76] #ZEXSM#add ODataQueryBuilderOptions --- src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs | 10 +++++++--- .../Builders/ODataQueryNestedBuilder.cs | 9 +++++++-- .../Conventions/Options/Nested/ODataOptionNested.cs | 7 ++++--- .../Conventions/Options/ODataOption.cs | 11 +++++++---- .../Conventions/Options/ODataOptionKey.cs | 7 ++++--- .../Conventions/Options/ODataOptionList.cs | 7 ++++--- src/OData.QueryBuilder/ODataQuery.cs | 7 ++++++- src/OData.QueryBuilder/ODataQueryNested.cs | 9 +++++++-- .../Options/ODataQueryBuilderOptions.cs | 8 ++++++++ 9 files changed, 54 insertions(+), 21 deletions(-) create mode 100644 src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index 666c3501..b13349df 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -1,5 +1,6 @@ using OData.QueryBuilder.Conventions.Constants; using OData.QueryBuilder.Conventions.Options; +using OData.QueryBuilder.Options; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; @@ -8,16 +9,19 @@ namespace OData.QueryBuilder.Builders { public class ODataQueryBuilder : IODataQueryBuilder { + private readonly ODataQueryBuilderOptions _odataQueryBuilderOptions; private readonly string _baseUrl; - public ODataQueryBuilder(Uri baseUrl) + public ODataQueryBuilder(Uri baseUrl, ODataQueryBuilderOptions odataQueryBuilderOptions = default) { _baseUrl = $"{baseUrl.OriginalString.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"; + _odataQueryBuilderOptions = odataQueryBuilderOptions ?? new ODataQueryBuilderOptions(); } - public ODataQueryBuilder(string baseUrl) + public ODataQueryBuilder(string baseUrl, ODataQueryBuilderOptions odataQueryBuilderOptions = default) { _baseUrl = $"{baseUrl.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"; + _odataQueryBuilderOptions = odataQueryBuilderOptions ?? new ODataQueryBuilderOptions(); } public IODataOption For(Expression> entityResource) @@ -25,7 +29,7 @@ public IODataOption For(Expression> en var visitor = new VisitorExpression(entityResource.Body); var query = visitor.ToString(); - return new ODataOption($"{_baseUrl}{query}"); + return new ODataOption($"{_baseUrl}{query}", _odataQueryBuilderOptions); } } } \ No newline at end of file diff --git a/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs index 82d87261..f740e639 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs @@ -1,4 +1,5 @@ using OData.QueryBuilder.Conventions.Options.Nested; +using OData.QueryBuilder.Options; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; @@ -8,11 +9,15 @@ namespace OData.QueryBuilder.Builders { public class ODataQueryNestedBuilder : IODataQueryNestedBuilder { + private readonly ODataQueryBuilderOptions _odataQueryBuilderOptions; private readonly StringBuilder _stringBuilder; private ODataQueryNested _odataQueryNested; - public ODataQueryNestedBuilder() => + public ODataQueryNestedBuilder(ODataQueryBuilderOptions odataQueryBuilderOptions) + { _stringBuilder = new StringBuilder(); + _odataQueryBuilderOptions = odataQueryBuilderOptions; + } public string Query => $"{_stringBuilder}({_odataQueryNested.Query})"; @@ -33,7 +38,7 @@ public IODataOptionNested For(Expression(); + _odataQueryNested = new ODataOptionNested(_odataQueryBuilderOptions); return _odataQueryNested as ODataOptionNested; } diff --git a/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs b/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs index 86c728ad..30527cf3 100644 --- a/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs +++ b/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs @@ -1,5 +1,6 @@ using OData.QueryBuilder.Builders; using OData.QueryBuilder.Conventions.Constants; +using OData.QueryBuilder.Options; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; @@ -9,8 +10,8 @@ namespace OData.QueryBuilder.Conventions.Options.Nested { public class ODataOptionNested : ODataQueryNested, IODataOptionNested { - public ODataOptionNested() - : base(new StringBuilder()) + public ODataOptionNested(ODataQueryBuilderOptions odataQueryBuilderOptions) + : base(new StringBuilder(), odataQueryBuilderOptions) { } @@ -26,7 +27,7 @@ public IODataOptionNested Expand(Expression> enti public IODataOptionNested Expand(Action> actionEntityExpandNested) { - var builder = new ODataQueryNestedBuilder(); + var builder = new ODataQueryNestedBuilder(_odataQueryBuilderOptions); actionEntityExpandNested(builder); diff --git a/src/OData.QueryBuilder/Conventions/Options/ODataOption.cs b/src/OData.QueryBuilder/Conventions/Options/ODataOption.cs index 4c30237e..f4c56a6c 100644 --- a/src/OData.QueryBuilder/Conventions/Options/ODataOption.cs +++ b/src/OData.QueryBuilder/Conventions/Options/ODataOption.cs @@ -1,36 +1,39 @@ using OData.QueryBuilder.Conventions.Constants; +using OData.QueryBuilder.Options; using System.Text; namespace OData.QueryBuilder.Conventions.Options { public class ODataOption : IODataOption { + private readonly ODataQueryBuilderOptions _odataQueryBuilderOptions; private readonly StringBuilder _stringBuilder; - public ODataOption(string resourceUrl) + public ODataOption(string resourceUrl, ODataQueryBuilderOptions odataQueryBuilderOptions) { _stringBuilder = new StringBuilder(resourceUrl); + _odataQueryBuilderOptions = odataQueryBuilderOptions; } public IODataOptionKey ByKey(int key) { _stringBuilder.Append($"({key}){QuerySeparators.BeginString}"); - return new ODataOptionKey(_stringBuilder); + return new ODataOptionKey(_stringBuilder, _odataQueryBuilderOptions); } public IODataOptionKey ByKey(string key) { _stringBuilder.Append($"('{key}'){QuerySeparators.BeginString}"); - return new ODataOptionKey(_stringBuilder); + return new ODataOptionKey(_stringBuilder, _odataQueryBuilderOptions); } public IODataOptionList ByList() { _stringBuilder.Append(QuerySeparators.BeginString); - return new ODataOptionList(_stringBuilder); + return new ODataOptionList(_stringBuilder, _odataQueryBuilderOptions); } } } diff --git a/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs b/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs index f77e884c..d9bfbff3 100644 --- a/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs +++ b/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs @@ -1,5 +1,6 @@ using OData.QueryBuilder.Builders; using OData.QueryBuilder.Conventions.Constants; +using OData.QueryBuilder.Options; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; @@ -9,8 +10,8 @@ namespace OData.QueryBuilder.Conventions.Options { public class ODataOptionKey : ODataQuery, IODataOptionKey { - public ODataOptionKey(StringBuilder stringBuilder) - : base(stringBuilder) + public ODataOptionKey(StringBuilder stringBuilder, ODataQueryBuilderOptions odataQueryBuilderOptions) + : base(stringBuilder, odataQueryBuilderOptions) { } @@ -26,7 +27,7 @@ public IODataOptionKey Expand(Expression> entityE public IODataOptionKey Expand(Action> actionEntityExpandNested) { - var builder = new ODataQueryNestedBuilder(); + var builder = new ODataQueryNestedBuilder(_odataQueryBuilderOptions); actionEntityExpandNested(builder); diff --git a/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs b/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs index 7ac33210..dc6c8f0a 100644 --- a/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs +++ b/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs @@ -2,6 +2,7 @@ using OData.QueryBuilder.Conventions.Constants; using OData.QueryBuilder.Conventions.Functions; using OData.QueryBuilder.Conventions.Operators; +using OData.QueryBuilder.Options; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; @@ -11,8 +12,8 @@ namespace OData.QueryBuilder.Conventions.Options { public class ODataOptionList : ODataQuery, IODataOptionList { - public ODataOptionList(StringBuilder stringBuilder) - : base(stringBuilder) + public ODataOptionList(StringBuilder stringBuilder, ODataQueryBuilderOptions odataQueryBuilderOptions) + : base(stringBuilder, odataQueryBuilderOptions) { } @@ -58,7 +59,7 @@ public IODataOptionList Expand(Expression> entity public IODataOptionList Expand(Action> entityExpandNested) { - var builder = new ODataQueryNestedBuilder(); + var builder = new ODataQueryNestedBuilder(_odataQueryBuilderOptions); entityExpandNested(builder); _stringBuilder.Append($"{ODataOptionNames.Expand}{QuerySeparators.EqualSignString}{builder.Query}{QuerySeparators.MainString}"); diff --git a/src/OData.QueryBuilder/ODataQuery.cs b/src/OData.QueryBuilder/ODataQuery.cs index 77c373d4..336aadb6 100644 --- a/src/OData.QueryBuilder/ODataQuery.cs +++ b/src/OData.QueryBuilder/ODataQuery.cs @@ -1,4 +1,5 @@ using OData.QueryBuilder.Conventions.Constants; +using OData.QueryBuilder.Options; using System; using System.Collections.Generic; using System.Text; @@ -7,10 +8,14 @@ namespace OData.QueryBuilder { public class ODataQuery : IODataQuery { + protected readonly ODataQueryBuilderOptions _odataQueryBuilderOptions; protected readonly StringBuilder _stringBuilder; - public ODataQuery(StringBuilder stringBuilder) => + public ODataQuery(StringBuilder stringBuilder, ODataQueryBuilderOptions odataQueryBuilderOptions) + { _stringBuilder = stringBuilder; + _odataQueryBuilderOptions = odataQueryBuilderOptions; + } public Dictionary ToDictionary() { diff --git a/src/OData.QueryBuilder/ODataQueryNested.cs b/src/OData.QueryBuilder/ODataQueryNested.cs index e8a7b9f4..978fdd16 100644 --- a/src/OData.QueryBuilder/ODataQueryNested.cs +++ b/src/OData.QueryBuilder/ODataQueryNested.cs @@ -1,14 +1,19 @@ using OData.QueryBuilder.Conventions.Constants; +using OData.QueryBuilder.Options; using System.Text; namespace OData.QueryBuilder { public class ODataQueryNested { + protected readonly ODataQueryBuilderOptions _odataQueryBuilderOptions; protected readonly StringBuilder _stringBuilder; - public ODataQueryNested(StringBuilder queryBuilder) => - _stringBuilder = queryBuilder; + public ODataQueryNested(StringBuilder stringBuilder, ODataQueryBuilderOptions odataQueryBuilderOptions) + { + _stringBuilder = stringBuilder; + _odataQueryBuilderOptions = odataQueryBuilderOptions; + } public string Query => _stringBuilder.ToString().Trim(QuerySeparators.NestedChar); } diff --git a/src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs b/src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs new file mode 100644 index 00000000..dd7c1987 --- /dev/null +++ b/src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs @@ -0,0 +1,8 @@ +namespace OData.QueryBuilder.Options +{ + public class ODataQueryBuilderOptions + { + public bool SuppressNullAndEmptyFunctionArguments { get; set; } = true; + public bool SuppressNullAndEmptyOperatorArguments { get; set; } = true; + } +} From 0ed565704745702f72aec0ef889ec4447b77b05f Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Wed, 24 Jun 2020 20:20:21 +0300 Subject: [PATCH 34/76] #ZEXSM#review --- .../Builders/ODataQueryBuilder.cs | 6 ++-- .../Builders/ODataQueryNestedBuilder.cs | 8 +++--- .../Options/Nested/ODataOptionNested.cs | 22 ++++++--------- .../Conventions/Options/ODataOptionKey.cs | 13 ++++----- .../Conventions/Options/ODataOptionList.cs | 28 ++++++++----------- .../Visitors/VisitorExpression.cs | 8 +++--- 6 files changed, 38 insertions(+), 47 deletions(-) diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index b13349df..d1277e5f 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -9,6 +9,7 @@ namespace OData.QueryBuilder.Builders { public class ODataQueryBuilder : IODataQueryBuilder { + internal readonly VisitorExpression _visitorExpression; private readonly ODataQueryBuilderOptions _odataQueryBuilderOptions; private readonly string _baseUrl; @@ -16,18 +17,19 @@ public ODataQueryBuilder(Uri baseUrl, ODataQueryBuilderOptions odataQueryBuilder { _baseUrl = $"{baseUrl.OriginalString.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"; _odataQueryBuilderOptions = odataQueryBuilderOptions ?? new ODataQueryBuilderOptions(); + _visitorExpression = new VisitorExpression(); } public ODataQueryBuilder(string baseUrl, ODataQueryBuilderOptions odataQueryBuilderOptions = default) { _baseUrl = $"{baseUrl.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"; _odataQueryBuilderOptions = odataQueryBuilderOptions ?? new ODataQueryBuilderOptions(); + _visitorExpression = new VisitorExpression(); } public IODataOption For(Expression> entityResource) { - var visitor = new VisitorExpression(entityResource.Body); - var query = visitor.ToString(); + var query = _visitorExpression.ToString(entityResource.Body); return new ODataOption($"{_baseUrl}{query}", _odataQueryBuilderOptions); } diff --git a/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs index f740e639..4387a3e0 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs @@ -12,11 +12,13 @@ public class ODataQueryNestedBuilder : IODataQueryNestedBuilder $"{_stringBuilder}({_odataQueryNested.Query})"; @@ -25,15 +27,13 @@ public IODataOptionNested For(Expression : ODataQueryNested, IODataOptionNested { + internal readonly VisitorExpression _visitorExpression; + public ODataOptionNested(ODataQueryBuilderOptions odataQueryBuilderOptions) - : base(new StringBuilder(), odataQueryBuilderOptions) - { - } + : base(new StringBuilder(), odataQueryBuilderOptions) => + _visitorExpression = new VisitorExpression(); public IODataOptionNested Expand(Expression> entityNestedExpand) { - var visitor = new VisitorExpression(entityNestedExpand.Body); - var query = visitor.ToString(); + var query = _visitorExpression.ToString(entityNestedExpand.Body); _stringBuilder.Append($"{ODataOptionNames.Expand}{QuerySeparators.EqualSignString}{query}{QuerySeparators.NestedString}"); @@ -38,8 +38,7 @@ public IODataOptionNested Expand(Action Filter(Expression> entityNestedFilter) { - var visitor = new VisitorExpression(entityNestedFilter.Body); - var query = visitor.ToString(); + var query = _visitorExpression.ToString(entityNestedFilter.Body); _stringBuilder.Append($"{ODataOptionNames.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.NestedString}"); @@ -48,8 +47,7 @@ public IODataOptionNested Filter(Expression> entity public IODataOptionNested OrderBy(Expression> entityNestedOrderBy) { - var visitor = new VisitorExpression(entityNestedOrderBy.Body); - var query = visitor.ToString(); + var query = _visitorExpression.ToString(entityNestedOrderBy.Body); _stringBuilder.Append($"{ODataOptionNames.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Asc}{QuerySeparators.NestedString}"); @@ -58,8 +56,7 @@ public IODataOptionNested OrderBy(Expression> ent public IODataOptionNested OrderByDescending(Expression> entityNestedOrderByDescending) { - var visitor = new VisitorExpression(entityNestedOrderByDescending.Body); - var query = visitor.ToString(); + var query = _visitorExpression.ToString(entityNestedOrderByDescending.Body); _stringBuilder.Append($"{ODataOptionNames.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Desc}{QuerySeparators.NestedString}"); @@ -68,8 +65,7 @@ public IODataOptionNested OrderByDescending(Expression Select(Expression> entityNestedSelect) { - var visitor = new VisitorExpression(entityNestedSelect.Body); - var query = visitor.ToString(); + var query = _visitorExpression.ToString(entityNestedSelect.Body); _stringBuilder.Append($"{ODataOptionNames.Select}{QuerySeparators.EqualSignString}{query}{QuerySeparators.NestedString}"); diff --git a/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs b/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs index d9bfbff3..d7bc6f76 100644 --- a/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs +++ b/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs @@ -10,15 +10,15 @@ namespace OData.QueryBuilder.Conventions.Options { public class ODataOptionKey : ODataQuery, IODataOptionKey { + internal readonly VisitorExpression _visitorExpression; + public ODataOptionKey(StringBuilder stringBuilder, ODataQueryBuilderOptions odataQueryBuilderOptions) - : base(stringBuilder, odataQueryBuilderOptions) - { - } + : base(stringBuilder, odataQueryBuilderOptions) => + _visitorExpression = new VisitorExpression(); public IODataOptionKey Expand(Expression> entityExpand) { - var visitor = new VisitorExpression(entityExpand.Body); - var query = visitor.ToString(); + var query = _visitorExpression.ToString(entityExpand.Body); _stringBuilder.Append($"{ODataOptionNames.Expand}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); @@ -38,8 +38,7 @@ public IODataOptionKey Expand(Action> public IODataOptionKey Select(Expression> entitySelect) { - var visitor = new VisitorExpression(entitySelect.Body); - var query = visitor.ToString(); + var query = _visitorExpression.ToString(entitySelect.Body); _stringBuilder.Append($"{ODataOptionNames.Select}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); diff --git a/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs b/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs index dc6c8f0a..7899fce9 100644 --- a/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs +++ b/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs @@ -12,15 +12,15 @@ namespace OData.QueryBuilder.Conventions.Options { public class ODataOptionList : ODataQuery, IODataOptionList { + internal readonly VisitorExpression _visitorExpression; + public ODataOptionList(StringBuilder stringBuilder, ODataQueryBuilderOptions odataQueryBuilderOptions) - : base(stringBuilder, odataQueryBuilderOptions) - { - } + : base(stringBuilder, odataQueryBuilderOptions) => + _visitorExpression = new VisitorExpression(); public IODataOptionList Filter(Expression> entityFilter) { - var visitor = new VisitorExpression(entityFilter.Body); - var query = visitor.ToString(); + var query = _visitorExpression.ToString(entityFilter.Body); _stringBuilder.Append($"{ODataOptionNames.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); @@ -29,8 +29,7 @@ public IODataOptionList Filter(Expression> entityFi public IODataOptionList Filter(Expression> entityFilter) { - var visitor = new VisitorExpression(entityFilter.Body); - var query = visitor.ToString(); + var query = _visitorExpression.ToString(entityFilter.Body); _stringBuilder.Append($"{ODataOptionNames.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); @@ -39,8 +38,7 @@ public IODataOptionList Filter(Expression Filter(Expression> entityFilter) { - var visitor = new VisitorExpression(entityFilter.Body); - var query = visitor.ToString(); + var query = _visitorExpression.ToString(entityFilter.Body); _stringBuilder.Append($"{ODataOptionNames.Filter}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); @@ -49,8 +47,7 @@ public IODataOptionList Filter(Expression Expand(Expression> entityExpand) { - var visitor = new VisitorExpression(entityExpand.Body); - var query = visitor.ToString(); + var query = _visitorExpression.ToString(entityExpand.Body); _stringBuilder.Append($"{ODataOptionNames.Expand}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); @@ -69,8 +66,7 @@ public IODataOptionList Expand(Action public IODataOptionList Select(Expression> entitySelect) { - var visitor = new VisitorExpression(entitySelect.Body); - var query = visitor.ToString(); + var query = _visitorExpression.ToString(entitySelect.Body); _stringBuilder.Append($"{ODataOptionNames.Select}{QuerySeparators.EqualSignString}{query}{QuerySeparators.MainString}"); @@ -79,8 +75,7 @@ public IODataOptionList Select(Expression> entity public IODataOptionList OrderBy(Expression> entityOrderBy) { - var visitor = new VisitorExpression(entityOrderBy.Body); - var query = visitor.ToString(); + var query = _visitorExpression.ToString(entityOrderBy.Body); _stringBuilder.Append($"{ODataOptionNames.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Asc}{QuerySeparators.MainString}"); @@ -89,8 +84,7 @@ public IODataOptionList OrderBy(Expression> entit public IODataOptionList OrderByDescending(Expression> entityOrderByDescending) { - var visitor = new VisitorExpression(entityOrderByDescending.Body); - var query = visitor.ToString(); + var query = _visitorExpression.ToString(entityOrderByDescending.Body); _stringBuilder.Append($"{ODataOptionNames.OrderBy}{QuerySeparators.EqualSignString}{query} {QuerySorts.Desc}{QuerySeparators.MainString}"); diff --git a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs index b9b2cdae..6d29fb3a 100644 --- a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs +++ b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs @@ -9,9 +9,9 @@ namespace OData.QueryBuilder.Visitors { internal class VisitorExpression { - private readonly Expression _expression; - - public VisitorExpression(Expression expression) => _expression = expression; + public VisitorExpression() + { + } protected virtual string VisitExpression(Expression expression) => expression switch { @@ -192,6 +192,6 @@ protected string CreateResourcePath(MemberExpression memberExpression) name : $"{name}/{memberExpression.Member.Name}"; } - public new string ToString() => VisitExpression(_expression); + public string ToString(Expression expression) => VisitExpression(expression); } } From db600e0af047b7896940f941b82e755c0cf95577 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Wed, 24 Jun 2020 22:36:27 +0300 Subject: [PATCH 35/76] #ZEXSM#add options suppes exception --- .../Builders/ODataQueryBuilder.cs | 4 +- .../Builders/ODataQueryNestedBuilder.cs | 2 +- .../Options/Nested/ODataOptionNested.cs | 2 +- .../Conventions/Options/ODataOptionKey.cs | 2 +- .../Conventions/Options/ODataOptionList.cs | 2 +- .../Extensions/ReflectionExtensions.cs | 4 +- .../Extensions/StringExtensions.cs | 8 + .../Options/ODataQueryBuilderOptions.cs | 4 +- .../Visitors/VisitorExpression.cs | 49 +++- test/OData.QueryBuilder.Test/CommonFixture.cs | 10 +- .../ODataQueryOptionKeyTest.cs | 4 +- .../ODataQueryOptionListTest.cs | 259 +++++++++++++----- 12 files changed, 263 insertions(+), 87 deletions(-) create mode 100644 src/OData.QueryBuilder/Extensions/StringExtensions.cs diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index d1277e5f..57b81693 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -17,14 +17,14 @@ public ODataQueryBuilder(Uri baseUrl, ODataQueryBuilderOptions odataQueryBuilder { _baseUrl = $"{baseUrl.OriginalString.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"; _odataQueryBuilderOptions = odataQueryBuilderOptions ?? new ODataQueryBuilderOptions(); - _visitorExpression = new VisitorExpression(); + _visitorExpression = new VisitorExpression(_odataQueryBuilderOptions); } public ODataQueryBuilder(string baseUrl, ODataQueryBuilderOptions odataQueryBuilderOptions = default) { _baseUrl = $"{baseUrl.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"; _odataQueryBuilderOptions = odataQueryBuilderOptions ?? new ODataQueryBuilderOptions(); - _visitorExpression = new VisitorExpression(); + _visitorExpression = new VisitorExpression(_odataQueryBuilderOptions); } public IODataOption For(Expression> entityResource) diff --git a/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs index 4387a3e0..44bbdfb0 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs @@ -18,7 +18,7 @@ public ODataQueryNestedBuilder(ODataQueryBuilderOptions odataQueryBuilderOptions { _stringBuilder = new StringBuilder(); _odataQueryBuilderOptions = odataQueryBuilderOptions; - _visitorExpression = new VisitorExpression(); + _visitorExpression = new VisitorExpression(_odataQueryBuilderOptions); } public string Query => $"{_stringBuilder}({_odataQueryNested.Query})"; diff --git a/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs b/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs index 053aa569..f13bf37d 100644 --- a/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs +++ b/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs @@ -14,7 +14,7 @@ public class ODataOptionNested : ODataQueryNested, IODataOptionNested - _visitorExpression = new VisitorExpression(); + _visitorExpression = new VisitorExpression(odataQueryBuilderOptions); public IODataOptionNested Expand(Expression> entityNestedExpand) { diff --git a/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs b/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs index d7bc6f76..6df477bb 100644 --- a/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs +++ b/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs @@ -14,7 +14,7 @@ public class ODataOptionKey : ODataQuery, IODataOptionKey - _visitorExpression = new VisitorExpression(); + _visitorExpression = new VisitorExpression(odataQueryBuilderOptions); public IODataOptionKey Expand(Expression> entityExpand) { diff --git a/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs b/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs index 7899fce9..16f5014f 100644 --- a/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs +++ b/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs @@ -16,7 +16,7 @@ public class ODataOptionList : ODataQuery, IODataOptionList - _visitorExpression = new VisitorExpression(); + _visitorExpression = new VisitorExpression(odataQueryBuilderOptions); public IODataOptionList Filter(Expression> entityFilter) { diff --git a/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs b/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs index 5da5afa4..3858ccc2 100644 --- a/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs @@ -46,11 +46,11 @@ public static string ConvertToString(object @object) case IEnumerable intValues: var intValuesString = string.Join(QuerySeparators.CommaString, intValues); - return !string.IsNullOrEmpty(intValuesString) ? intValuesString : default; + return !string.IsNullOrEmpty(intValuesString) ? intValuesString : string.Empty; case IEnumerable stringValues: var stringValuesString = string.Join($"'{QuerySeparators.CommaString}'", stringValues); - return !string.IsNullOrEmpty(stringValuesString) ? $"'{stringValuesString}'" : default; + return !string.IsNullOrEmpty(stringValuesString) ? $"'{stringValuesString}'" : string.Empty; default: return $"{@object}"; } diff --git a/src/OData.QueryBuilder/Extensions/StringExtensions.cs b/src/OData.QueryBuilder/Extensions/StringExtensions.cs new file mode 100644 index 00000000..eaa0ace2 --- /dev/null +++ b/src/OData.QueryBuilder/Extensions/StringExtensions.cs @@ -0,0 +1,8 @@ +namespace OData.QueryBuilder.Extensions +{ + internal static class StringExtensions + { + public static bool IsNullOrQuotes(this string value) => + string.IsNullOrEmpty(value) || value == "''"; + } +} diff --git a/src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs b/src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs index dd7c1987..b55f87dd 100644 --- a/src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs +++ b/src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs @@ -2,7 +2,7 @@ { public class ODataQueryBuilderOptions { - public bool SuppressNullAndEmptyFunctionArguments { get; set; } = true; - public bool SuppressNullAndEmptyOperatorArguments { get; set; } = true; + public bool SuppressExceptionOfNullOrEmptyFunctionArguments { get; set; } = true; + public bool SuppressExceptionOfNullOrEmptyOperatorArguments { get; set; } = true; } } diff --git a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs index 6d29fb3a..0cad2e18 100644 --- a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs +++ b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs @@ -2,6 +2,7 @@ using OData.QueryBuilder.Conventions.Functions; using OData.QueryBuilder.Conventions.Operators; using OData.QueryBuilder.Extensions; +using OData.QueryBuilder.Options; using System; using System.Linq.Expressions; @@ -9,9 +10,10 @@ namespace OData.QueryBuilder.Visitors { internal class VisitorExpression { - public VisitorExpression() - { - } + protected readonly ODataQueryBuilderOptions _odataQueryBuilderOptions; + + public VisitorExpression(ODataQueryBuilderOptions odataQueryBuilderOptions) => + _odataQueryBuilderOptions = odataQueryBuilderOptions; protected virtual string VisitExpression(Expression expression) => expression switch { @@ -57,8 +59,17 @@ protected virtual string VisitMethodCallExpression(MethodCallExpression methodCa { case nameof(IODataOperator.In): var in0 = VisitExpression(methodCallExpression.Arguments[0]); - var in1 = VisitExpression(methodCallExpression.Arguments[1]) ?? - throw new ArgumentException("Enumeration is empty or null"); + var in1 = ReflectionExtensions.ConvertToString(GetValueOfExpression(methodCallExpression.Arguments[1])); + + if (in1.IsNullOrQuotes()) + { + if (!_odataQueryBuilderOptions.SuppressExceptionOfNullOrEmptyOperatorArguments) + { + throw new ArgumentException("Enumeration is empty or null"); + } + + return default; + } return $"{in0} {ODataOperatorNames.In} ({in1})"; case nameof(IODataOperator.All): @@ -76,15 +87,35 @@ protected virtual string VisitMethodCallExpression(MethodCallExpression methodCa return $"{ODataFunctionNames.Date}({date0})"; case nameof(IODataFunction.SubstringOf): - var substringOf0 = GetValueOfExpression(methodCallExpression.Arguments[0]); + var substringOf0 = ReflectionExtensions.ConvertToString(GetValueOfExpression(methodCallExpression.Arguments[0])); var substringOf1 = VisitExpression(methodCallExpression.Arguments[1]); - return $"{ODataFunctionNames.SubstringOf}('{substringOf0}',{substringOf1})"; + if (substringOf0.IsNullOrQuotes()) + { + if (!_odataQueryBuilderOptions.SuppressExceptionOfNullOrEmptyFunctionArguments) + { + throw new ArgumentException("Value is empty or null"); + } + + return default; + } + + return $"{ODataFunctionNames.SubstringOf}({substringOf0},{substringOf1})"; case nameof(IODataFunction.Contains): var contains0 = VisitExpression(methodCallExpression.Arguments[0]); - var contains1 = GetValueOfExpression(methodCallExpression.Arguments[1]); + var contains1 = ReflectionExtensions.ConvertToString(GetValueOfExpression(methodCallExpression.Arguments[1])); + + if (contains1.IsNullOrQuotes()) + { + if (!_odataQueryBuilderOptions.SuppressExceptionOfNullOrEmptyFunctionArguments) + { + throw new ArgumentException("Value is empty or null"); + } + + return default; + } - return $"{ODataFunctionNames.Contains}({contains0},'{contains1}')"; + return $"{ODataFunctionNames.Contains}({contains0},{contains1})"; case nameof(IODataStringFunction.ToUpper): var toUpper0 = VisitExpression(methodCallExpression.Arguments[0]); diff --git a/test/OData.QueryBuilder.Test/CommonFixture.cs b/test/OData.QueryBuilder.Test/CommonFixture.cs index 128a9513..6208e9ef 100644 --- a/test/OData.QueryBuilder.Test/CommonFixture.cs +++ b/test/OData.QueryBuilder.Test/CommonFixture.cs @@ -1,5 +1,4 @@ -using OData.QueryBuilder.Builders; -using OData.QueryBuilder.Test.Fakes; +using System; namespace OData.QueryBuilder.Test { @@ -7,11 +6,10 @@ public class CommonFixture { public CommonFixture() { - ODataQueryBuilder1 = new ODataQueryBuilder("http://mock/odata/"); - ODataQueryBuilder2 = new ODataQueryBuilder(new System.Uri("http://mock/odata/")); } - public ODataQueryBuilder ODataQueryBuilder1 { get; private set; } - public ODataQueryBuilder ODataQueryBuilder2 { get; private set; } + public string BaseUrl => "http://mock/odata/"; + + public Uri BaseUri => new Uri("http://mock/odata/"); } } diff --git a/test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs b/test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs index 86f74fea..685e63ed 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs @@ -1,5 +1,6 @@ using FluentAssertions; using OData.QueryBuilder.Builders; +using OData.QueryBuilder.Options; using OData.QueryBuilder.Test.Fakes; using System.Linq; using Xunit; @@ -11,7 +12,8 @@ public class ODataQueryOptionKeyTest : IClassFixture private readonly ODataQueryBuilder _odataQueryBuilder; public ODataQueryOptionKeyTest(CommonFixture commonFixture) => - _odataQueryBuilder = commonFixture.ODataQueryBuilder1; + _odataQueryBuilder = new ODataQueryBuilder( + commonFixture.BaseUrl, new ODataQueryBuilderOptions()); [Fact(DisplayName = "Expand simple => Success")] public void ODataQueryBuilderKey_Expand_Simple_Success() diff --git a/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs b/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs index 674b185c..171ec05a 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs @@ -1,5 +1,6 @@ using FluentAssertions; using OData.QueryBuilder.Builders; +using OData.QueryBuilder.Options; using OData.QueryBuilder.Test.Fakes; using System; using System.Collections.Generic; @@ -10,17 +11,22 @@ namespace OData.QueryBuilder.Test { public class ODataQueryOptionListTest : IClassFixture { - private readonly ODataQueryBuilder _odataQueryBuilder; + private readonly CommonFixture _commonFixture; + private readonly ODataQueryBuilder _odataQueryBuilderDefault; public static string IdCodeStatic => "testCode"; - public ODataQueryOptionListTest(CommonFixture commonFixture) => - _odataQueryBuilder = commonFixture.ODataQueryBuilder2; + public ODataQueryOptionListTest(CommonFixture commonFixture) + { + _commonFixture = commonFixture; + _odataQueryBuilderDefault = new ODataQueryBuilder( + commonFixture.BaseUri, new ODataQueryBuilderOptions()); + } [Fact(DisplayName = "Expand simple => Success")] public void ODataQueryBuilderList_Expand_Simple_Success() { - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Expand(s => new { s.ODataKind }) @@ -32,7 +38,7 @@ public void ODataQueryBuilderList_Expand_Simple_Success() [Fact(DisplayName = "Expand nested => Success")] public void ODataQueryBuilderList_ExpandNested_Success() { - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Expand(f => @@ -53,7 +59,7 @@ public void ODataQueryBuilderList_ExpandNested_Success() [Fact(DisplayName = "Expand nested orderby => Success")] public void ODataQueryBuilderList_ExpandNested_OrderBy_Success() { - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Expand(f => @@ -70,7 +76,7 @@ public void ODataQueryBuilderList_ExpandNested_OrderBy_Success() [Fact(DisplayName = "Expand nested top => Success")] public void ODataQueryBuilderList_ExpandNested_Top_Success() { - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Expand(f => @@ -88,7 +94,7 @@ public void ODataQueryBuilderList_ExpandNested_Top_Success() [Fact(DisplayName = "Expand nested orderby desc => Success")] public void ODataQueryBuilderList_ExpandNested_OrderByDescending_Success() { - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Expand(f => @@ -105,7 +111,7 @@ public void ODataQueryBuilderList_ExpandNested_OrderByDescending_Success() [Fact(DisplayName = "Select simple => Success")] public void ODataQueryBuilderList_Select_Simple_Success() { - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Select(s => s.IdType) @@ -117,7 +123,7 @@ public void ODataQueryBuilderList_Select_Simple_Success() [Fact(DisplayName = "OrderBy simple => Success")] public void ODataQueryBuilderList_OrderBy_Simple_Success() { - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .OrderBy(s => s.IdType) @@ -129,7 +135,7 @@ public void ODataQueryBuilderList_OrderBy_Simple_Success() [Fact(DisplayName = "OrderByDescending simple => Success")] public void ODataQueryBuilderList_OrderByDescending_Simple_Success() { - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .OrderByDescending(s => s.IdType) @@ -141,7 +147,7 @@ public void ODataQueryBuilderList_OrderByDescending_Simple_Success() [Fact(DisplayName = "Count simple => Success")] public void ODataQueryBuilderList_Count_Simple_Success() { - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Count() @@ -153,7 +159,7 @@ public void ODataQueryBuilderList_Count_Simple_Success() [Fact(DisplayName = "Skip and Top simple => Success")] public void ODataQueryBuilderList_Skip_Top_Simple_Success() { - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Skip(1) @@ -166,7 +172,7 @@ public void ODataQueryBuilderList_Skip_Top_Simple_Success() [Fact(DisplayName = "Filter simple const int=> Success")] public void ODataQueryBuilderList_Filter_Simple_Const_Int_Success() { - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Filter(s => s.ODataKind.ODataCode.IdCode >= 3 || s.IdType == 5) @@ -179,7 +185,7 @@ public void ODataQueryBuilderList_Filter_Simple_Const_Int_Success() public void ODataQueryBuilderList_Filter_Simple_Const_String_Success() { var constValue = "3"; - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Filter(s => @@ -193,7 +199,7 @@ public void ODataQueryBuilderList_Filter_Simple_Const_String_Success() [Fact(DisplayName = "Filter operators All/Any => Success")] public void ODataQueryBuilderList_Filter_All_Any_Success() { - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Filter((s, f, o) => o.Any(s.ODataKind.ODataCodes, v => v.IdCode == 1) @@ -209,7 +215,7 @@ public void ODataQueryBuilderList_Expand_Filter_Select_OrderBy_OrderByDescending var constValue = 2; var constCurrentDate = DateTime.Today.ToString("yyyy-MM-dd"); - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Expand(s => new { s.ODataKind }) @@ -235,7 +241,7 @@ public void ODataQueryBuilderList_Function_Date_Success() var currentDateNow = new DateTime(2019, 2, 9, 1, 2, 4); var newObject = new ODataTypeEntity { ODataKind = new ODataKindEntity { EndDate = currentDateToday } }; - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Filter((s, f) => @@ -271,7 +277,7 @@ public void ODataQueryBuilderList_Function_Datetime_convert_Success() { var currentDateToday = new DateTime?(new DateTime(2019, 2, 9)); - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Filter((s, f) => @@ -286,7 +292,7 @@ public void ODataQueryBuilderList_Function_Datetime_convert_exception() { var currentDateToday = new DateTime?(new DateTime(2019, 2, 9)); - _odataQueryBuilder.Invoking((q) => q + _odataQueryBuilderDefault.Invoking((q) => q .For(s => s.ODataType) .ByList() .Filter((s, f) => @@ -300,7 +306,7 @@ public void ODataQueryBuilderList_Function_Datetimeoffset_convert_Success() { var currentDateToday = new DateTimeOffset?(new DateTime(2019, 2, 9)); - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Filter((s, f) => @@ -315,7 +321,7 @@ public void ODataQueryBuilderList_Function_Datetimeoffset_convert_exception() { var currentDateToday = new DateTimeOffset?(new DateTime(2019, 2, 9)); - _odataQueryBuilder.Invoking((q) => q + _odataQueryBuilderDefault.Invoking((q) => q .For(s => s.ODataType) .ByList() .Filter((s, f) => @@ -324,49 +330,64 @@ public void ODataQueryBuilderList_Function_Datetimeoffset_convert_exception() .Should().Throw(); } - [Fact(DisplayName = "Operator IN => Success")] - public void ODataQueryBuilderList_Operator_In_Success() + [Fact(DisplayName = "SubstringOf with ToUpper Simple Test => Success")] + public void ODataQueryBuilderList_Test_Substringof_Simple() { - var constStrIds = new[] { "123", "512" }; - var constStrListIds = new[] { "123", "512" }.ToList(); - var constIntIds = new[] { 123, 512 }; - var constIntListIds = new[] { 123, 512 }.ToList(); - var newObject = new ODataTypeEntity { ODataKind = new ODataKindEntity { Sequence = constIntListIds } }; - var newObjectSequenceArray = new ODataTypeEntity { ODataKind = new ODataKindEntity { SequenceArray = constIntIds } }; - - var uri = _odataQueryBuilder + var constValue = "p".ToUpper(); + var newObject = new ODataTypeEntity { TypeCode = "TypeCodeValue".ToUpper() }; + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() - .Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, constStrIds) - && o.In(s.ODataKind.ODataCode.Code, constStrIds) - && o.In(s.ODataKind.ODataCode.Code, constStrListIds) - && o.In(s.IdType, constIntIds) - && o.In(s.IdType, constIntListIds) - && o.In((int)s.IdRule, constIntIds) - && o.In((int)s.IdRule, constIntListIds) - && o.In(s.ODataKind.IdKind, newObject.ODataKind.Sequence) - && o.In(s.ODataKind.ODataCode.IdCode, newObjectSequenceArray.ODataKind.SequenceArray)) + .Filter((s, f) => + f.SubstringOf("W", f.ToUpper(s.ODataKind.ODataCode.Code)) + || f.SubstringOf(constValue, s.ODataKind.ODataCode.Code) + || f.SubstringOf(newObject.TypeCode, s.ODataKindNew.ODataCode.Code) + || f.SubstringOf("55", s.ODataKindNew.ODataCode.Code)) .ToUri(); - uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=ODataKind/ODataCode/Code in ('123','512') and ODataKind/ODataCode/Code in ('123','512') and ODataKind/ODataCode/Code in ('123','512') and IdType in (123,512) and IdType in (123,512) and IdRule in (123,512) and IdRule in (123,512) and ODataKind/IdKind in (123,512) and ODataKind/ODataCode/IdCode in (123,512)"); + uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=substringof('W',toupper(ODataKind/ODataCode/Code)) or substringof('P',ODataKind/ODataCode/Code) or substringof('TYPECODEVALUE',ODataKindNew/ODataCode/Code) or substringof('55',ODataKindNew/ODataCode/Code)"); } - [Fact(DisplayName = "SubstringOf with ToUpper Simple Test => Success")] - public void ODataQueryBuilderList_Test_Substringof_Simple() + [Fact(DisplayName = "SubstringOf is null or empty value => Success")] + public void ODataQueryBuilderList_Test_SubstringOf_is_null_or_empty_value_Success() { var constValue = "p".ToUpper(); - var newObject = new ODataTypeEntity { TypeCode = "TypeCodeValue".ToUpper() }; - var uri = _odataQueryBuilder + var newObject = new ODataTypeEntity { TypeCode = string.Empty }; + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Filter((s, f) => - f.SubstringOf("W", f.ToUpper(s.ODataKind.ODataCode.Code)) + f.SubstringOf(string.Empty, f.ToUpper(s.ODataKind.ODataCode.Code)) || f.SubstringOf(constValue, s.ODataKind.ODataCode.Code) || f.SubstringOf(newObject.TypeCode, s.ODataKindNew.ODataCode.Code) - || f.SubstringOf("55", s.ODataKindNew.ODataCode.Code)) + || f.SubstringOf(null, s.ODataKindNew.ODataCode.Code)) .ToUri(); - uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=substringof('W',toupper(ODataKind/ODataCode/Code)) or substringof('P',ODataKind/ODataCode/Code) or substringof('TYPECODEVALUE',ODataKindNew/ODataCode/Code) or substringof('55',ODataKindNew/ODataCode/Code)"); + uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=substringof('P',ODataKind/ODataCode/Code)"); + } + + + [Fact(DisplayName = "SubstringOf is null or empty value => ArgumentException")] + public void ODataQueryBuilderList_Test_Substringof_is_null_or_empty_value_ArgumentException() + { + var constValue = default(string); + var newObject = new ODataTypeEntity { TypeCode = string.Empty }; + + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyFunctionArguments = false }; + var odataQueryBuilder = new ODataQueryBuilder( + _commonFixture.BaseUri, odataQueryBuilderOptions); + + odataQueryBuilder.Invoking( + (r) => r + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => + f.SubstringOf(null, f.ToUpper(s.ODataKind.ODataCode.Code)) + || f.SubstringOf(constValue, s.ODataKind.ODataCode.Code) + || f.SubstringOf(newObject.TypeCode, s.ODataKindNew.ODataCode.Code) + || f.SubstringOf(string.Empty, s.ODataKindNew.ODataCode.Code)) + .ToUri()) + .Should().Throw().WithMessage("Value is empty or null"); } [Fact(DisplayName = "Contains with ToLower Simple Test => Success")] @@ -374,7 +395,7 @@ public void ODataQueryBuilderList_Test_Contains_Simple() { var constValue = "p".ToLower(); var newObject = new ODataTypeEntity { TypeCode = "TypeCodeValue".ToLower() }; - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Filter((s, f) => @@ -387,12 +408,112 @@ public void ODataQueryBuilderList_Test_Contains_Simple() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=contains(tolower(ODataKind/ODataCode/Code),'W') or contains(ODataKind/ODataCode/Code,'p') or contains(ODataKindNew/ODataCode/Code,'typecodevalue') or contains(ODataKindNew/ODataCode/Code,'55')"); } + [Fact(DisplayName = "Contains is null or empty value => ArgumentException")] + public void ODataQueryBuilderList_Test_Contains_is_null_or_empty_value_ArgumentException() + { + var constValue = default(string); + var newObject = new ODataTypeEntity { TypeCode = string.Empty }; + + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyFunctionArguments = false }; + var odataQueryBuilder = new ODataQueryBuilder( + _commonFixture.BaseUri, odataQueryBuilderOptions); + + odataQueryBuilder.Invoking( + (r) => r + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => + f.Contains(f.ToLower(s.ODataKind.ODataCode.Code), null) + || f.Contains(s.ODataKind.ODataCode.Code, constValue) + || f.Contains(s.ODataKindNew.ODataCode.Code, newObject.TypeCode) + || f.Contains(s.ODataKindNew.ODataCode.Code, string.Empty)) + .ToUri()) + .Should().Throw().WithMessage("Value is empty or null"); + } + + [Fact(DisplayName = "Contains is null or empty value => Success")] + public void ODataQueryBuilderList_Test_Contains_is_null_or_empty_value_Success() + { + var constValue = "P"; + var newObject = new ODataTypeEntity { TypeCode = string.Empty }; + var uri = _odataQueryBuilderDefault + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => + f.Contains(f.ToLower(s.ODataKind.ODataCode.Code), null) + || f.Contains(s.ODataKind.ODataCode.Code, constValue) + || f.Contains(s.ODataKindNew.ODataCode.Code, newObject.TypeCode) + || f.Contains(s.ODataKindNew.ODataCode.Code, string.Empty)) + .ToUri(); + + uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=contains(ODataKind/ODataCode/Code,'P')"); + } + + [Fact(DisplayName = "Operator IN => Success")] + public void ODataQueryBuilderList_Operator_In_Success() + { + var constStrIds = new[] { "123", "512" }; + var constStrListIds = new[] { "123", "512" }.ToList(); + var constIntIds = new[] { 123, 512 }; + var constIntListIds = new[] { 123, 512 }.ToList(); + var newObject = new ODataTypeEntity { ODataKind = new ODataKindEntity { Sequence = constIntListIds } }; + var newObjectSequenceArray = new ODataTypeEntity { ODataKind = new ODataKindEntity { SequenceArray = constIntIds } }; + + var uri = _odataQueryBuilderDefault + .For(s => s.ODataType) + .ByList() + .Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, constStrIds) + && o.In(s.ODataKind.ODataCode.Code, constStrIds) + && o.In(s.ODataKind.ODataCode.Code, constStrListIds) + && o.In(s.IdType, constIntIds) + && o.In(s.IdType, constIntListIds) + && o.In((int)s.IdRule, constIntIds) + && o.In((int)s.IdRule, constIntListIds) + && o.In(s.ODataKind.IdKind, newObject.ODataKind.Sequence) + && o.In(s.ODataKind.ODataCode.IdCode, newObjectSequenceArray.ODataKind.SequenceArray)) + .ToUri(); + + uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=ODataKind/ODataCode/Code in ('123','512') and ODataKind/ODataCode/Code in ('123','512') and ODataKind/ODataCode/Code in ('123','512') and IdType in (123,512) and IdType in (123,512) and IdRule in (123,512) and IdRule in (123,512) and ODataKind/IdKind in (123,512) and ODataKind/ODataCode/IdCode in (123,512)"); + } + + [Fact(DisplayName = "(ODataQueryBuilderList) Operator IN empty => Success")] + public void ODataQueryBuilderList_Operator_In_Empty_Success() + { + var constStrIds = default(IEnumerable); + var constEmprtyStrListIds = new string[] { }.ToList(); + var constIntIds = default(int[]); + var constEmptyIntIds = new int[0]; + var constIntListIds = new[] { 123, 512 }.ToList(); + var newObject = new ODataTypeEntity { ODataKind = new ODataKindEntity { Sequence = constIntListIds } }; + var newObjectSequenceArray = new ODataTypeEntity { ODataKind = new ODataKindEntity { SequenceArray = constIntIds } }; + + var uri = _odataQueryBuilderDefault + .For(s => s.ODataType) + .ByList() + .Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, constStrIds) + && o.In(s.ODataKind.ODataCode.Code, constEmprtyStrListIds) + && o.In(s.IdType, constIntIds) + && o.In(s.IdType, constEmptyIntIds) + && o.In(s.IdType, constIntListIds) + && o.In((int)s.IdRule, constIntIds) + && o.In((int)s.IdRule, constIntListIds) + && o.In(s.ODataKind.IdKind, newObject.ODataKind.Sequence) + && o.In(s.ODataKind.ODataCode.IdCode, newObjectSequenceArray.ODataKind.SequenceArray)) + .ToUri(); + + uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=IdType in (123,512) and IdRule in (123,512) and ODataKind/IdKind in (123,512)"); + } + [Fact(DisplayName = "Operator IN is null => ArgumentException 1")] public void ODataQueryBuilderList_Operator_In_is_null_1() { var constEmprtyStrListIds = new string[] { }.ToList(); - _odataQueryBuilder.Invoking( + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArguments = false }; + var odataQueryBuilder = new ODataQueryBuilder( + _commonFixture.BaseUri, odataQueryBuilderOptions); + + odataQueryBuilder.Invoking( (r) => r .For(s => s.ODataType) .ByList() @@ -406,7 +527,11 @@ public void ODataQueryBuilderList_Operator_In_is_null_2() { var constStrIds = default(IEnumerable); - _odataQueryBuilder.Invoking( + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArguments = false }; + var odataQueryBuilder = new ODataQueryBuilder( + _commonFixture.BaseUri, odataQueryBuilderOptions); + + odataQueryBuilder.Invoking( (r) => r .For(s => s.ODataType) .ByList() @@ -420,7 +545,11 @@ public void ODataQueryBuilderList_Operator_In_is_null_3() { var constIntIds = default(int[]); - _odataQueryBuilder.Invoking( + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArguments = false }; + var odataQueryBuilder = new ODataQueryBuilder( + _commonFixture.BaseUri, odataQueryBuilderOptions); + + odataQueryBuilder.Invoking( (r) => r .For(s => s.ODataType) .ByList() @@ -435,7 +564,11 @@ public void ODataQueryBuilderList_Operator_In_is_null_4() var constIntIds = default(int[]); var newObjectSequenceArray = new ODataTypeEntity { ODataKind = new ODataKindEntity { SequenceArray = constIntIds } }; - _odataQueryBuilder.Invoking( + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArguments = false }; + var odataQueryBuilder = new ODataQueryBuilder( + _commonFixture.BaseUri, odataQueryBuilderOptions); + + odataQueryBuilder.Invoking( (r) => r .For(s => s.ODataType) .ByList() @@ -449,7 +582,11 @@ public void ODataQueryBuilderList_Operator_In_is_empty_1() { var constEmptyIntIds = new int[0]; - _odataQueryBuilder.Invoking( + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArguments = false }; + var odataQueryBuilder = new ODataQueryBuilder( + _commonFixture.BaseUri, odataQueryBuilderOptions); + + odataQueryBuilder.Invoking( (r) => r .For(s => s.ODataType) .ByList() @@ -464,7 +601,7 @@ public void ODataQueryBuilderList_Filter_Boolean_Values_Success() var constValue = false; var newObject = new ODataTypeEntity { IsOpen = false }; - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Filter(s => s.IsActive @@ -482,7 +619,7 @@ public void ODataQueryBuilderList_Filter_Brackets_Success() var constStrIds = new[] { "123", "512" }; var constValue = 3; - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Filter((s, f, o) => s.IdRule == constValue @@ -500,7 +637,7 @@ public void ODataQueryBuilderList_Filter_Brackets_Success() [InlineData(false)] public void ODataQueryBuilderList_Count_Value_Success(bool value) { - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Count(value) @@ -512,7 +649,7 @@ public void ODataQueryBuilderList_Count_Value_Success(bool value) [Fact(DisplayName = "Filter not bool => Success")] public void ODataQueryBuilderList_Filter_Not__Bool_Success() { - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Filter(s => s.IsActive && !(bool)s.IsOpen) @@ -527,7 +664,7 @@ public void ToDicionaryTest() var constValue = false; var newObject = new ODataTypeEntity { IsOpen = false }; - var dictionary = _odataQueryBuilder + var dictionary = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Filter(s => s.IsActive @@ -551,7 +688,7 @@ public void ToDicionaryTest() [Fact(DisplayName = "Filter Enum")] public void FilterEnumTest() { - var uri = _odataQueryBuilder + var uri = _odataQueryBuilderDefault .For(s => s.ODataType) .ByList() .Filter((s, f) => s.ODataKind.Color == f.ConvertEnumToString(ColorEnum.Blue) From 855459a98b0cb26200921245c99d24c3b1a22366 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 11:38:44 +0300 Subject: [PATCH 36/76] #ZEXSM#add rc version#travis --- .travis.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index c5b97e82..b41e1a32 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,10 +25,12 @@ before_deploy: - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - CURRENT_PATCH=$(echo $LAST_TAG | cut -d. -f 3) + - CURRENT_RC=$(echo $LAST_TAG | cut -d. -f 4) - MAJOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1)) || echo $CURRENT_MAJOR) - - MINOR=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - - PATCH=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - - NEW_TAG=$(echo $MAJOR.$MINOR.$PATCH) + - MINOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) + - PATCH=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) && ([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo 0) || echo $(($CURRENT_PATCH+1))) + - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || && echo '') + - NEW_TAG=$(echo $MAJOR.$MINOR.$PATCH$RC) - PACKAGE_VERSION=${NEW_TAG:-$DEFAULT_PACKAGE_VERSION} - git tag v$PACKAGE_VERSION && git push origin v$PACKAGE_VERSION - dotnet pack -c $CONFIGURATION -p:PackageVersion=$PACKAGE_VERSION From 0dfe0c637db73536149893bd222cd639665170ff Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 11:41:22 +0300 Subject: [PATCH 37/76] #ZEXSM#fix travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b41e1a32..4d39609c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,7 @@ before_deploy: - CURRENT_RC=$(echo $LAST_TAG | cut -d. -f 4) - MAJOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1)) || echo $CURRENT_MAJOR) - MINOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - - PATCH=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) && ([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo 0) || echo $(($CURRENT_PATCH+1))) + - PATCH=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || && echo '') - NEW_TAG=$(echo $MAJOR.$MINOR.$PATCH$RC) - PACKAGE_VERSION=${NEW_TAG:-$DEFAULT_PACKAGE_VERSION} From a2585a3507cc1805bc19803cd4534c475be5e855 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 12:08:41 +0300 Subject: [PATCH 38/76] #ZEXSM#test --- .travis.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.travis.yml b/.travis.yml index 4d39609c..9c8daf8c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,17 @@ before_script: script: - dotnet build - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION -f netcoreapp2.1 + - PR_TITLE=Merge pull request #1 from zesm/release/test + - LAST_TAG=v1.4.9 + - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) + - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) + - CURRENT_PATCH=$(echo $LAST_TAG | cut -d. -f 3) + - CURRENT_RC=$(echo $LAST_TAG | cut -d. -f 4) + - MAJOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1)) || echo $CURRENT_MAJOR) + - MINOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) + - PATCH=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) + - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || && echo '') + - echo $MAJOR.$MINOR.$PATCH$RC after_success: - cd src/OData.QueryBuilder && dotnet minicover instrument --workdir ../../coverage --parentdir ../ --assemblies test/**/bin/$CONFIGURATION/**/*.dll --sources src/**/*.cs && dotnet minicover reset --workdir ../../coverage && cd ../../ - dotnet test --no-build ./test/OData.QueryBuilder.Test From 536766c52097206cab9768d1bc9c557acacaa1ea Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 12:21:16 +0300 Subject: [PATCH 39/76] #ZEX#dotnet: 3.1.300 --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9c8daf8c..1cf7f4da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: csharp dist: trusty os: linux mono: none -dotnet: 2.1.502 +dotnet: 3.1.300 env: global: - secure: SuKoVIfbXNAQQAQ8FhoK/USbDAJld63DKsBkmqONvUyOm8rBzFPkAfIl0qACKMMVJec7aJ9PhfxBA8nJdh7zCuaw0xcGxnVfQaxtegKo8+yz18LtUDnwv7h2aDDpsL5IdtgNZabusoz0CG0RB2vZEUQCbx80oH41L0Ijcya93ngnVeD4u0PdoFXbqxoBTiadI6qh/Od+jD+6+B04fz2XSa16WSjobSwsYNr5M+CIpa9OmLdZAJkvgHFlshmrAD2oE8iddImB9YIjDqCvnH/jqAP3/Eqci/N5sW5qpgRAyhvRxcI3Gev0wFexN8qMBUB3Iim92hf18s30R9K0Bvbb/Q+HX/VgnIBY8Yy3F68YNQvmga5AoODyuLaqPBe6ptckFp6yPkPBqeQgp1Pu2mySL0tFkjvg6/WWsxLVpco7zCjymF1IDhjVgbeO+rAQ5vEs1Fp89o4mpIAOcP10uM2b3W71fFSWTbKvIyp8ozL8PaTkRq5NiS7NvQ85hE/lVJyCL62vZ1YYOeQb0ArdoCZVdHbZp9L3UAIPYGUW6mJ9PlQtm9RC3hsnBJEvpoBnQl1wx25hhnTt16oif6L8h5XAbgVpW0Bd46LXMQbMXHKFyeMTuH4l94N9HD+qiDh82L95EQk+yHeCmfZqoKE+pf7HuscvHiFLkOxNbtJdPXqF99k= @@ -21,8 +21,8 @@ script: - CURRENT_PATCH=$(echo $LAST_TAG | cut -d. -f 3) - CURRENT_RC=$(echo $LAST_TAG | cut -d. -f 4) - MAJOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1)) || echo $CURRENT_MAJOR) - - MINOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - - PATCH=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) + - MINOR=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) + - PATCH=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || && echo '') - echo $MAJOR.$MINOR.$PATCH$RC after_success: From af906e2d370f1ca862eb05332d9cc433e43bd4f8 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 12:24:47 +0300 Subject: [PATCH 40/76] #ZEXSM#fix travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1cf7f4da..8b9ffeff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: csharp dist: trusty os: linux mono: none -dotnet: 3.1.300 +dotnet: 3.1 env: global: - secure: SuKoVIfbXNAQQAQ8FhoK/USbDAJld63DKsBkmqONvUyOm8rBzFPkAfIl0qACKMMVJec7aJ9PhfxBA8nJdh7zCuaw0xcGxnVfQaxtegKo8+yz18LtUDnwv7h2aDDpsL5IdtgNZabusoz0CG0RB2vZEUQCbx80oH41L0Ijcya93ngnVeD4u0PdoFXbqxoBTiadI6qh/Od+jD+6+B04fz2XSa16WSjobSwsYNr5M+CIpa9OmLdZAJkvgHFlshmrAD2oE8iddImB9YIjDqCvnH/jqAP3/Eqci/N5sW5qpgRAyhvRxcI3Gev0wFexN8qMBUB3Iim92hf18s30R9K0Bvbb/Q+HX/VgnIBY8Yy3F68YNQvmga5AoODyuLaqPBe6ptckFp6yPkPBqeQgp1Pu2mySL0tFkjvg6/WWsxLVpco7zCjymF1IDhjVgbeO+rAQ5vEs1Fp89o4mpIAOcP10uM2b3W71fFSWTbKvIyp8ozL8PaTkRq5NiS7NvQ85hE/lVJyCL62vZ1YYOeQb0ArdoCZVdHbZp9L3UAIPYGUW6mJ9PlQtm9RC3hsnBJEvpoBnQl1wx25hhnTt16oif6L8h5XAbgVpW0Bd46LXMQbMXHKFyeMTuH4l94N9HD+qiDh82L95EQk+yHeCmfZqoKE+pf7HuscvHiFLkOxNbtJdPXqF99k= From 11b3145476add540b9d164588ddf1bb7909c4da6 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 12:27:40 +0300 Subject: [PATCH 41/76] travis test --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8b9ffeff..8cc31952 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: csharp dist: trusty os: linux mono: none -dotnet: 3.1 +dotnet: 3.1.202 env: global: - secure: SuKoVIfbXNAQQAQ8FhoK/USbDAJld63DKsBkmqONvUyOm8rBzFPkAfIl0qACKMMVJec7aJ9PhfxBA8nJdh7zCuaw0xcGxnVfQaxtegKo8+yz18LtUDnwv7h2aDDpsL5IdtgNZabusoz0CG0RB2vZEUQCbx80oH41L0Ijcya93ngnVeD4u0PdoFXbqxoBTiadI6qh/Od+jD+6+B04fz2XSa16WSjobSwsYNr5M+CIpa9OmLdZAJkvgHFlshmrAD2oE8iddImB9YIjDqCvnH/jqAP3/Eqci/N5sW5qpgRAyhvRxcI3Gev0wFexN8qMBUB3Iim92hf18s30R9K0Bvbb/Q+HX/VgnIBY8Yy3F68YNQvmga5AoODyuLaqPBe6ptckFp6yPkPBqeQgp1Pu2mySL0tFkjvg6/WWsxLVpco7zCjymF1IDhjVgbeO+rAQ5vEs1Fp89o4mpIAOcP10uM2b3W71fFSWTbKvIyp8ozL8PaTkRq5NiS7NvQ85hE/lVJyCL62vZ1YYOeQb0ArdoCZVdHbZp9L3UAIPYGUW6mJ9PlQtm9RC3hsnBJEvpoBnQl1wx25hhnTt16oif6L8h5XAbgVpW0Bd46LXMQbMXHKFyeMTuH4l94N9HD+qiDh82L95EQk+yHeCmfZqoKE+pf7HuscvHiFLkOxNbtJdPXqF99k= From 90ea707231717934678502991764c16dfe619c20 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 12:33:53 +0300 Subject: [PATCH 42/76] travis test --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8cc31952..f7209189 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,7 @@ language: csharp -dist: trusty -os: linux +dotnet: 3.1 mono: none -dotnet: 3.1.202 +solution: OData.QueryBuilder.sln env: global: - secure: SuKoVIfbXNAQQAQ8FhoK/USbDAJld63DKsBkmqONvUyOm8rBzFPkAfIl0qACKMMVJec7aJ9PhfxBA8nJdh7zCuaw0xcGxnVfQaxtegKo8+yz18LtUDnwv7h2aDDpsL5IdtgNZabusoz0CG0RB2vZEUQCbx80oH41L0Ijcya93ngnVeD4u0PdoFXbqxoBTiadI6qh/Od+jD+6+B04fz2XSa16WSjobSwsYNr5M+CIpa9OmLdZAJkvgHFlshmrAD2oE8iddImB9YIjDqCvnH/jqAP3/Eqci/N5sW5qpgRAyhvRxcI3Gev0wFexN8qMBUB3Iim92hf18s30R9K0Bvbb/Q+HX/VgnIBY8Yy3F68YNQvmga5AoODyuLaqPBe6ptckFp6yPkPBqeQgp1Pu2mySL0tFkjvg6/WWsxLVpco7zCjymF1IDhjVgbeO+rAQ5vEs1Fp89o4mpIAOcP10uM2b3W71fFSWTbKvIyp8ozL8PaTkRq5NiS7NvQ85hE/lVJyCL62vZ1YYOeQb0ArdoCZVdHbZp9L3UAIPYGUW6mJ9PlQtm9RC3hsnBJEvpoBnQl1wx25hhnTt16oif6L8h5XAbgVpW0Bd46LXMQbMXHKFyeMTuH4l94N9HD+qiDh82L95EQk+yHeCmfZqoKE+pf7HuscvHiFLkOxNbtJdPXqF99k= From a7f9e7e864c6a869e30b698cbddd024774ebf718 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 12:39:17 +0300 Subject: [PATCH 43/76] #ZEXSM#up lib test --- .travis.yml | 2 +- .../OData.QueryBuilder.Test.csproj | 29 +++++++++---------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index f7209189..aad5a06e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ script: - MAJOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1)) || echo $CURRENT_MAJOR) - MINOR=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - PATCH=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || && echo '') + - RC=$(([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || && echo '') - echo $MAJOR.$MINOR.$PATCH$RC after_success: - cd src/OData.QueryBuilder && dotnet minicover instrument --workdir ../../coverage --parentdir ../ --assemblies test/**/bin/$CONFIGURATION/**/*.dll --sources src/**/*.cs && dotnet minicover reset --workdir ../../coverage && cd ../../ diff --git a/test/OData.QueryBuilder.Test/OData.QueryBuilder.Test.csproj b/test/OData.QueryBuilder.Test/OData.QueryBuilder.Test.csproj index f5fd28be..950ca398 100644 --- a/test/OData.QueryBuilder.Test/OData.QueryBuilder.Test.csproj +++ b/test/OData.QueryBuilder.Test/OData.QueryBuilder.Test.csproj @@ -1,16 +1,15 @@ - - - - netcoreapp2.1 - false - - - - - - - - - - + + + netcoreapp3.1 + false + + + + + + + + + + \ No newline at end of file From 8f7d1dbacb1ffae344d7929b93e01090f4c5cc04 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 12:42:42 +0300 Subject: [PATCH 44/76] travis fix --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index aad5a06e..84051083 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,9 +12,9 @@ before_script: - dotnet restore script: - dotnet build - - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION -f netcoreapp2.1 + - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION - PR_TITLE=Merge pull request #1 from zesm/release/test - - LAST_TAG=v1.4.9 + - LAST_TAG=1.4.9 - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - CURRENT_PATCH=$(echo $LAST_TAG | cut -d. -f 3) From 4d2bf4876ae59045bd373978e40641c3b402a1ee Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 12:43:39 +0300 Subject: [PATCH 45/76] travis test --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 84051083..9d86ed77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ before_script: script: - dotnet build - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION - - PR_TITLE=Merge pull request #1 from zesm/release/test + - PR_TITLE='Merge pull request #1 from zesm/release/test' - LAST_TAG=1.4.9 - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) From 87c807f1419bce62fa79b3952ca9920ab4e17d92 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 12:48:54 +0300 Subject: [PATCH 46/76] travis test --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9d86ed77..ce29d704 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ before_script: script: - dotnet build - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION - - PR_TITLE='Merge pull request #1 from zesm/release/test' + - PR_TITLE='Merge-pull-request-#1-from-zesm/release/test' - LAST_TAG=1.4.9 - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) @@ -22,7 +22,7 @@ script: - MAJOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1)) || echo $CURRENT_MAJOR) - MINOR=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - PATCH=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - - RC=$(([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || && echo '') + - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || && echo '') - echo $MAJOR.$MINOR.$PATCH$RC after_success: - cd src/OData.QueryBuilder && dotnet minicover instrument --workdir ../../coverage --parentdir ../ --assemblies test/**/bin/$CONFIGURATION/**/*.dll --sources src/**/*.cs && dotnet minicover reset --workdir ../../coverage && cd ../../ From 06e539ba93d8e28365054650ec2dbf8ed6c9f167 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 12:54:04 +0300 Subject: [PATCH 47/76] #travis test --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ce29d704..02512e2a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,7 @@ script: - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION - PR_TITLE='Merge-pull-request-#1-from-zesm/release/test' - LAST_TAG=1.4.9 + - RC_PREFIX='-rc.' - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - CURRENT_PATCH=$(echo $LAST_TAG | cut -d. -f 3) @@ -22,7 +23,7 @@ script: - MAJOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1)) || echo $CURRENT_MAJOR) - MINOR=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - PATCH=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || && echo '') + - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo $((RC_PREFIX))$((CURRENT_RC+1)) || && echo '') - echo $MAJOR.$MINOR.$PATCH$RC after_success: - cd src/OData.QueryBuilder && dotnet minicover instrument --workdir ../../coverage --parentdir ../ --assemblies test/**/bin/$CONFIGURATION/**/*.dll --sources src/**/*.cs && dotnet minicover reset --workdir ../../coverage && cd ../../ From 41ad8dca25e3496663b166c4db425ed1727b912d Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 12:57:03 +0300 Subject: [PATCH 48/76] travis test --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 02512e2a..ccd14f23 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,10 +12,9 @@ before_script: - dotnet restore script: - dotnet build - - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION + - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION -f netcoreapp3.1 - PR_TITLE='Merge-pull-request-#1-from-zesm/release/test' - LAST_TAG=1.4.9 - - RC_PREFIX='-rc.' - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - CURRENT_PATCH=$(echo $LAST_TAG | cut -d. -f 3) @@ -23,7 +22,7 @@ script: - MAJOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1)) || echo $CURRENT_MAJOR) - MINOR=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - PATCH=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo $((RC_PREFIX))$((CURRENT_RC+1)) || && echo '') + - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || echo '') - echo $MAJOR.$MINOR.$PATCH$RC after_success: - cd src/OData.QueryBuilder && dotnet minicover instrument --workdir ../../coverage --parentdir ../ --assemblies test/**/bin/$CONFIGURATION/**/*.dll --sources src/**/*.cs && dotnet minicover reset --workdir ../../coverage && cd ../../ From 5d2206487969dcdc8a4be4d2876941a659f16f31 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 12:59:31 +0300 Subject: [PATCH 49/76] travis test --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ccd14f23..51e7d3d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ before_script: script: - dotnet build - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION -f netcoreapp3.1 - - PR_TITLE='Merge-pull-request-#1-from-zesm/release/test' + - PR_TITLE='Merge-pull-request-#1-from-zesm/release-rc/test' - LAST_TAG=1.4.9 - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) From d5cff917f9e94b86a998887267aec1ea4d4505b0 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 13:26:44 +0300 Subject: [PATCH 50/76] travis test --- .travis.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 51e7d3d2..fc9d2bda 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ env: - secure: SuKoVIfbXNAQQAQ8FhoK/USbDAJld63DKsBkmqONvUyOm8rBzFPkAfIl0qACKMMVJec7aJ9PhfxBA8nJdh7zCuaw0xcGxnVfQaxtegKo8+yz18LtUDnwv7h2aDDpsL5IdtgNZabusoz0CG0RB2vZEUQCbx80oH41L0Ijcya93ngnVeD4u0PdoFXbqxoBTiadI6qh/Od+jD+6+B04fz2XSa16WSjobSwsYNr5M+CIpa9OmLdZAJkvgHFlshmrAD2oE8iddImB9YIjDqCvnH/jqAP3/Eqci/N5sW5qpgRAyhvRxcI3Gev0wFexN8qMBUB3Iim92hf18s30R9K0Bvbb/Q+HX/VgnIBY8Yy3F68YNQvmga5AoODyuLaqPBe6ptckFp6yPkPBqeQgp1Pu2mySL0tFkjvg6/WWsxLVpco7zCjymF1IDhjVgbeO+rAQ5vEs1Fp89o4mpIAOcP10uM2b3W71fFSWTbKvIyp8ozL8PaTkRq5NiS7NvQ85hE/lVJyCL62vZ1YYOeQb0ArdoCZVdHbZp9L3UAIPYGUW6mJ9PlQtm9RC3hsnBJEvpoBnQl1wx25hhnTt16oif6L8h5XAbgVpW0Bd46LXMQbMXHKFyeMTuH4l94N9HD+qiDh82L95EQk+yHeCmfZqoKE+pf7HuscvHiFLkOxNbtJdPXqF99k= branches: only: + - rc - master before_script: - dotnet restore @@ -24,6 +25,8 @@ script: - PATCH=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || echo '') - echo $MAJOR.$MINOR.$PATCH$RC + - echo $TRAVIS_TAG + - echo $TRAVIS_BRANCH after_success: - cd src/OData.QueryBuilder && dotnet minicover instrument --workdir ../../coverage --parentdir ../ --assemblies test/**/bin/$CONFIGURATION/**/*.dll --sources src/**/*.cs && dotnet minicover reset --workdir ../../coverage && cd ../../ - dotnet test --no-build ./test/OData.QueryBuilder.Test @@ -51,6 +54,8 @@ deploy: cleanup: true repo: ZEXSM/OData.QueryBuilder on: - branch: master + branch: + - rc + - master after_deploy: - dotnet nuget push ./src/OData.QueryBuilder/bin/Release/OData.QueryBuilder.$PACKAGE_VERSION.nupkg -k $NUGET_API_KEY -s $NUGET_SOURCE \ No newline at end of file From 421d2c8a00bc617045816e444631eea2138636ce Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 13:48:31 +0300 Subject: [PATCH 51/76] travis test --- .travis.yml | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/.travis.yml b/.travis.yml index fc9d2bda..889e8d24 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,19 +14,6 @@ before_script: script: - dotnet build - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION -f netcoreapp3.1 - - PR_TITLE='Merge-pull-request-#1-from-zesm/release-rc/test' - - LAST_TAG=1.4.9 - - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - - CURRENT_PATCH=$(echo $LAST_TAG | cut -d. -f 3) - - CURRENT_RC=$(echo $LAST_TAG | cut -d. -f 4) - - MAJOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1)) || echo $CURRENT_MAJOR) - - MINOR=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - - PATCH=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || echo '') - - echo $MAJOR.$MINOR.$PATCH$RC - - echo $TRAVIS_TAG - - echo $TRAVIS_BRANCH after_success: - cd src/OData.QueryBuilder && dotnet minicover instrument --workdir ../../coverage --parentdir ../ --assemblies test/**/bin/$CONFIGURATION/**/*.dll --sources src/**/*.cs && dotnet minicover reset --workdir ../../coverage && cd ../../ - dotnet test --no-build ./test/OData.QueryBuilder.Test @@ -39,10 +26,10 @@ before_deploy: - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - CURRENT_PATCH=$(echo $LAST_TAG | cut -d. -f 3) - CURRENT_RC=$(echo $LAST_TAG | cut -d. -f 4) - - MAJOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1)) || echo $CURRENT_MAJOR) - - MINOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - - PATCH=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || && echo '') + - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || echo '') + - MAJOR=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1))) || echo $CURRENT_MAJOR) + - MINOR=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) + - PATCH=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - NEW_TAG=$(echo $MAJOR.$MINOR.$PATCH$RC) - PACKAGE_VERSION=${NEW_TAG:-$DEFAULT_PACKAGE_VERSION} - git tag v$PACKAGE_VERSION && git push origin v$PACKAGE_VERSION From 295b3ab95172f892a6e1afa7e0a7929356ab9fe8 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 13:49:47 +0300 Subject: [PATCH 52/76] travis test --- .travis.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.travis.yml b/.travis.yml index 889e8d24..a3655abd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,17 @@ before_script: script: - dotnet build - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION -f netcoreapp3.1 + - PR_TITLE='Merge-pull-request-#1-from-zesm/release-rc/test' + - LAST_TAG=1.4.9 + - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) + - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) + - CURRENT_PATCH=$(echo $LAST_TAG | cut -d. -f 3) + - CURRENT_RC=$(echo $LAST_TAG | cut -d. -f 4) + - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || echo '') + - MAJOR=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1))) || echo $CURRENT_MAJOR) + - MINOR=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) + - PATCH=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) + - echo $MAJOR.$MINOR.$PATCH$RC after_success: - cd src/OData.QueryBuilder && dotnet minicover instrument --workdir ../../coverage --parentdir ../ --assemblies test/**/bin/$CONFIGURATION/**/*.dll --sources src/**/*.cs && dotnet minicover reset --workdir ../../coverage && cd ../../ - dotnet test --no-build ./test/OData.QueryBuilder.Test From 43d0fc68015ace8f3e36c6edf65c6c31fd806734 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 13:52:53 +0300 Subject: [PATCH 53/76] travis test --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a3655abd..022358be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ script: - dotnet build - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION -f netcoreapp3.1 - PR_TITLE='Merge-pull-request-#1-from-zesm/release-rc/test' - - LAST_TAG=1.4.9 + - LAST_TAG=2.0.0-rc.1 - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - CURRENT_PATCH=$(echo $LAST_TAG | cut -d. -f 3) From b14b8a9207a6134b5b19792e929e5e2af794b9e4 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 13:54:06 +0300 Subject: [PATCH 54/76] travis test --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 022358be..052550d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ before_script: script: - dotnet build - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION -f netcoreapp3.1 - - PR_TITLE='Merge-pull-request-#1-from-zesm/release-rc/test' + - PR_TITLE='Merge-pull-request-#1-from-zesm/reled/test' - LAST_TAG=2.0.0-rc.1 - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) From bae4f7de59e3becf13f41230d87615782be4c10a Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 15:20:54 +0300 Subject: [PATCH 55/76] #ZEXSM#fix --- .travis.yml | 2 +- .../Options/ODataQueryBuilderOptions.cs | 4 ++-- .../Visitors/VisitorExpression.cs | 6 +++--- .../ODataQueryOptionListTest.cs | 14 +++++++------- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 052550d3..93c90625 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ before_script: script: - dotnet build - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION -f netcoreapp3.1 - - PR_TITLE='Merge-pull-request-#1-from-zesm/reled/test' + - PR_TITLE='Merge-pull-request-#1-from-zesm/release/test' - LAST_TAG=2.0.0-rc.1 - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) diff --git a/src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs b/src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs index b55f87dd..baa879a0 100644 --- a/src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs +++ b/src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs @@ -2,7 +2,7 @@ { public class ODataQueryBuilderOptions { - public bool SuppressExceptionOfNullOrEmptyFunctionArguments { get; set; } = true; - public bool SuppressExceptionOfNullOrEmptyOperatorArguments { get; set; } = true; + public bool SuppressExceptionOfNullOrEmptyFunctionArgs { get; set; } = true; + public bool SuppressExceptionOfNullOrEmptyOperatorArgs { get; set; } = true; } } diff --git a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs index 0cad2e18..41c38f0c 100644 --- a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs +++ b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs @@ -63,7 +63,7 @@ protected virtual string VisitMethodCallExpression(MethodCallExpression methodCa if (in1.IsNullOrQuotes()) { - if (!_odataQueryBuilderOptions.SuppressExceptionOfNullOrEmptyOperatorArguments) + if (!_odataQueryBuilderOptions.SuppressExceptionOfNullOrEmptyOperatorArgs) { throw new ArgumentException("Enumeration is empty or null"); } @@ -92,7 +92,7 @@ protected virtual string VisitMethodCallExpression(MethodCallExpression methodCa if (substringOf0.IsNullOrQuotes()) { - if (!_odataQueryBuilderOptions.SuppressExceptionOfNullOrEmptyFunctionArguments) + if (!_odataQueryBuilderOptions.SuppressExceptionOfNullOrEmptyFunctionArgs) { throw new ArgumentException("Value is empty or null"); } @@ -107,7 +107,7 @@ protected virtual string VisitMethodCallExpression(MethodCallExpression methodCa if (contains1.IsNullOrQuotes()) { - if (!_odataQueryBuilderOptions.SuppressExceptionOfNullOrEmptyFunctionArguments) + if (!_odataQueryBuilderOptions.SuppressExceptionOfNullOrEmptyFunctionArgs) { throw new ArgumentException("Value is empty or null"); } diff --git a/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs b/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs index 171ec05a..ea11fa4b 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs @@ -373,7 +373,7 @@ public void ODataQueryBuilderList_Test_Substringof_is_null_or_empty_value_Argume var constValue = default(string); var newObject = new ODataTypeEntity { TypeCode = string.Empty }; - var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyFunctionArguments = false }; + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyFunctionArgs = false }; var odataQueryBuilder = new ODataQueryBuilder( _commonFixture.BaseUri, odataQueryBuilderOptions); @@ -414,7 +414,7 @@ public void ODataQueryBuilderList_Test_Contains_is_null_or_empty_value_ArgumentE var constValue = default(string); var newObject = new ODataTypeEntity { TypeCode = string.Empty }; - var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyFunctionArguments = false }; + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyFunctionArgs = false }; var odataQueryBuilder = new ODataQueryBuilder( _commonFixture.BaseUri, odataQueryBuilderOptions); @@ -509,7 +509,7 @@ public void ODataQueryBuilderList_Operator_In_is_null_1() { var constEmprtyStrListIds = new string[] { }.ToList(); - var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArguments = false }; + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArgs = false }; var odataQueryBuilder = new ODataQueryBuilder( _commonFixture.BaseUri, odataQueryBuilderOptions); @@ -527,7 +527,7 @@ public void ODataQueryBuilderList_Operator_In_is_null_2() { var constStrIds = default(IEnumerable); - var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArguments = false }; + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArgs = false }; var odataQueryBuilder = new ODataQueryBuilder( _commonFixture.BaseUri, odataQueryBuilderOptions); @@ -545,7 +545,7 @@ public void ODataQueryBuilderList_Operator_In_is_null_3() { var constIntIds = default(int[]); - var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArguments = false }; + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArgs = false }; var odataQueryBuilder = new ODataQueryBuilder( _commonFixture.BaseUri, odataQueryBuilderOptions); @@ -564,7 +564,7 @@ public void ODataQueryBuilderList_Operator_In_is_null_4() var constIntIds = default(int[]); var newObjectSequenceArray = new ODataTypeEntity { ODataKind = new ODataKindEntity { SequenceArray = constIntIds } }; - var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArguments = false }; + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArgs = false }; var odataQueryBuilder = new ODataQueryBuilder( _commonFixture.BaseUri, odataQueryBuilderOptions); @@ -582,7 +582,7 @@ public void ODataQueryBuilderList_Operator_In_is_empty_1() { var constEmptyIntIds = new int[0]; - var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArguments = false }; + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArgs = false }; var odataQueryBuilder = new ODataQueryBuilder( _commonFixture.BaseUri, odataQueryBuilderOptions); From cf44e6f3a37c405a676e17dbaa2d7b9735792131 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 15:27:58 +0300 Subject: [PATCH 56/76] #ZEX#up minicover --- .config/dotnet-tools.json | 12 ++++++++++++ .travis.yml | 2 +- OData.QueryBuilder.sln | 10 ++++++++-- src/OData.QueryBuilder/OData.QueryBuilder.csproj | 6 +++--- 4 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 .config/dotnet-tools.json diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 00000000..1309283d --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "minicover": { + "version": "3.0.6", + "commands": [ + "minicover" + ] + } + } +} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 93c90625..12051554 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ script: - MAJOR=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1))) || echo $CURRENT_MAJOR) - MINOR=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - PATCH=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - - echo $MAJOR.$MINOR.$PATCH$RC + - echo $(([ "$(echo $RC)" == "" ] && echo $CURRENT_MAJOR.$CURRENT_MINOR.$CURRENT_PATCH) || echo $MAJOR.$MINOR.$PATCH$RC) after_success: - cd src/OData.QueryBuilder && dotnet minicover instrument --workdir ../../coverage --parentdir ../ --assemblies test/**/bin/$CONFIGURATION/**/*.dll --sources src/**/*.cs && dotnet minicover reset --workdir ../../coverage && cd ../../ - dotnet test --no-build ./test/OData.QueryBuilder.Test diff --git a/OData.QueryBuilder.sln b/OData.QueryBuilder.sln index 3c164e7d..6014ff28 100644 --- a/OData.QueryBuilder.sln +++ b/OData.QueryBuilder.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.705 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30204.135 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{FA1582AB-A13D-44A4-A46D-2DAE1111A2BB}" EndProject @@ -17,6 +17,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "items", "items", "{179F88B9 README.md = README.md EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".config", ".config", "{B8F31CF9-EDE2-4813-A9AC-EBF3514FFE82}" + ProjectSection(SolutionItems) = preProject + .config\dotnet-tools.json = .config\dotnet-tools.json + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -38,6 +43,7 @@ Global GlobalSection(NestedProjects) = preSolution {E4D8F027-2B79-4794-9B75-D08C2BA066B8} = {FA1582AB-A13D-44A4-A46D-2DAE1111A2BB} {537E849E-5291-49F9-BD2A-9F4A01DB1561} = {26982440-340F-48A2-9D73-44DB6C52EBF1} + {B8F31CF9-EDE2-4813-A9AC-EBF3514FFE82} = {179F88B9-A06D-4505-9266-A5D66004601C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1D51B9A3-94B0-48DF-BFF5-110B13303535} diff --git a/src/OData.QueryBuilder/OData.QueryBuilder.csproj b/src/OData.QueryBuilder/OData.QueryBuilder.csproj index e04f94a7..b9ec970a 100644 --- a/src/OData.QueryBuilder/OData.QueryBuilder.csproj +++ b/src/OData.QueryBuilder/OData.QueryBuilder.csproj @@ -6,12 +6,12 @@ version=$(PackageVersion) latest - - - Always + + + From f93118a11c94564b2721e0a4bead60ac6218321b Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 15:35:07 +0300 Subject: [PATCH 57/76] travis test --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 12051554..87607171 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ script: - LAST_TAG=2.0.0-rc.1 - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - - CURRENT_PATCH=$(echo $LAST_TAG | cut -d. -f 3) + - CURRENT_PATCH=$(echo $(echo $LAST_TAG | cut -d. -f 3) | cut -d- -f 1) - CURRENT_RC=$(echo $LAST_TAG | cut -d. -f 4) - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || echo '') - MAJOR=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1))) || echo $CURRENT_MAJOR) From b9d8cdfd2dd3112369351a46beabb06aa3702791 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 15:49:01 +0300 Subject: [PATCH 58/76] trafis test --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 87607171..041e959a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ script: - dotnet build - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION -f netcoreapp3.1 - PR_TITLE='Merge-pull-request-#1-from-zesm/release/test' - - LAST_TAG=2.0.0-rc.1 + - LAST_TAG=2.0.0 - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - CURRENT_PATCH=$(echo $(echo $LAST_TAG | cut -d. -f 3) | cut -d- -f 1) From 4972ce0c6ea49d02e4f294a3db453da619a81cbe Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 16:21:10 +0300 Subject: [PATCH 59/76] travis test --- .travis.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 041e959a..6070b559 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,15 +16,21 @@ script: - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION -f netcoreapp3.1 - PR_TITLE='Merge-pull-request-#1-from-zesm/release/test' - LAST_TAG=2.0.0 + - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - CURRENT_PATCH=$(echo $(echo $LAST_TAG | cut -d. -f 3) | cut -d- -f 1) - CURRENT_RC=$(echo $LAST_TAG | cut -d. -f 4) - - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || echo '') - - MAJOR=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1))) || echo $CURRENT_MAJOR) - - MINOR=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - - PATCH=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - - echo $(([ "$(echo $RC)" == "" ] && echo $CURRENT_MAJOR.$CURRENT_MINOR.$CURRENT_PATCH) || echo $MAJOR.$MINOR.$PATCH$RC) + + - RELEASE_RC_BRANCH=$(echo $PR_TITLE | grep -oP 'release-rc') + - RELEASE_BRANCH=$(echo $PR_TITLE | grep -oP 'release') + - FEATURE_BRANCH=$(echo $PR_TITLE | grep -oP 'feature') + + - MAJOR=$(([ $RELEASE_RC_BRANCH == "release-rc" ] && echo 0) || ([ $RELEASE_BRANCH == "release" ] && echo $(($CURRENT_MAJOR+1))) || echo $CURRENT_MAJOR) + - MINOR=$(([ $RELEASE_RC_BRANCH == "release-rc" ] && echo 0) || ([ $RELEASE_BRANCH == "release" ] && echo 0) || ([ $FEATURE_BRANCH == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) + - PATCH=$(([ $RELEASE_RC_BRANCH == "release-rc" ] && echo 0) || ([ $RELEASE_BRANCH == "release" ] && echo 0) || ([ $FEATURE_BRANCH == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) + - RC_PREFIX=$([ $RELEASE_RC_BRANCH == "release-rc" ] && echo $((CURRENT_RC+1)) || echo '') + - echo $(([ $RELEASE_RC_BRANCH == "release-rc" ] && echo $MAJOR.$MINOR.$PATCH-rc.$RC_PREFIX) || echo $MAJOR.$MINOR.$PATCH) after_success: - cd src/OData.QueryBuilder && dotnet minicover instrument --workdir ../../coverage --parentdir ../ --assemblies test/**/bin/$CONFIGURATION/**/*.dll --sources src/**/*.cs && dotnet minicover reset --workdir ../../coverage && cd ../../ - dotnet test --no-build ./test/OData.QueryBuilder.Test From 1a51abc98df28b4ba7ee4acaff42b4b9d538e09e Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 16:30:15 +0300 Subject: [PATCH 60/76] travis test --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6070b559..996abb26 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,11 +21,9 @@ script: - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - CURRENT_PATCH=$(echo $(echo $LAST_TAG | cut -d. -f 3) | cut -d- -f 1) - CURRENT_RC=$(echo $LAST_TAG | cut -d. -f 4) - - RELEASE_RC_BRANCH=$(echo $PR_TITLE | grep -oP 'release-rc') - RELEASE_BRANCH=$(echo $PR_TITLE | grep -oP 'release') - FEATURE_BRANCH=$(echo $PR_TITLE | grep -oP 'feature') - - MAJOR=$(([ $RELEASE_RC_BRANCH == "release-rc" ] && echo 0) || ([ $RELEASE_BRANCH == "release" ] && echo $(($CURRENT_MAJOR+1))) || echo $CURRENT_MAJOR) - MINOR=$(([ $RELEASE_RC_BRANCH == "release-rc" ] && echo 0) || ([ $RELEASE_BRANCH == "release" ] && echo 0) || ([ $FEATURE_BRANCH == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - PATCH=$(([ $RELEASE_RC_BRANCH == "release-rc" ] && echo 0) || ([ $RELEASE_BRANCH == "release" ] && echo 0) || ([ $FEATURE_BRANCH == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) From 0857dd33008765f3244a924cad6f17d3bff160cf Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 16:34:39 +0300 Subject: [PATCH 61/76] travis --- .travis.yml | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/.travis.yml b/.travis.yml index 996abb26..acf8f3d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,28 +7,12 @@ env: - secure: SuKoVIfbXNAQQAQ8FhoK/USbDAJld63DKsBkmqONvUyOm8rBzFPkAfIl0qACKMMVJec7aJ9PhfxBA8nJdh7zCuaw0xcGxnVfQaxtegKo8+yz18LtUDnwv7h2aDDpsL5IdtgNZabusoz0CG0RB2vZEUQCbx80oH41L0Ijcya93ngnVeD4u0PdoFXbqxoBTiadI6qh/Od+jD+6+B04fz2XSa16WSjobSwsYNr5M+CIpa9OmLdZAJkvgHFlshmrAD2oE8iddImB9YIjDqCvnH/jqAP3/Eqci/N5sW5qpgRAyhvRxcI3Gev0wFexN8qMBUB3Iim92hf18s30R9K0Bvbb/Q+HX/VgnIBY8Yy3F68YNQvmga5AoODyuLaqPBe6ptckFp6yPkPBqeQgp1Pu2mySL0tFkjvg6/WWsxLVpco7zCjymF1IDhjVgbeO+rAQ5vEs1Fp89o4mpIAOcP10uM2b3W71fFSWTbKvIyp8ozL8PaTkRq5NiS7NvQ85hE/lVJyCL62vZ1YYOeQb0ArdoCZVdHbZp9L3UAIPYGUW6mJ9PlQtm9RC3hsnBJEvpoBnQl1wx25hhnTt16oif6L8h5XAbgVpW0Bd46LXMQbMXHKFyeMTuH4l94N9HD+qiDh82L95EQk+yHeCmfZqoKE+pf7HuscvHiFLkOxNbtJdPXqF99k= branches: only: - - rc - master before_script: - dotnet restore script: - dotnet build - dotnet test ./test/OData.QueryBuilder.Test -c $CONFIGURATION -f netcoreapp3.1 - - PR_TITLE='Merge-pull-request-#1-from-zesm/release/test' - - LAST_TAG=2.0.0 - - - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - - CURRENT_PATCH=$(echo $(echo $LAST_TAG | cut -d. -f 3) | cut -d- -f 1) - - CURRENT_RC=$(echo $LAST_TAG | cut -d. -f 4) - - RELEASE_RC_BRANCH=$(echo $PR_TITLE | grep -oP 'release-rc') - - RELEASE_BRANCH=$(echo $PR_TITLE | grep -oP 'release') - - FEATURE_BRANCH=$(echo $PR_TITLE | grep -oP 'feature') - - MAJOR=$(([ $RELEASE_RC_BRANCH == "release-rc" ] && echo 0) || ([ $RELEASE_BRANCH == "release" ] && echo $(($CURRENT_MAJOR+1))) || echo $CURRENT_MAJOR) - - MINOR=$(([ $RELEASE_RC_BRANCH == "release-rc" ] && echo 0) || ([ $RELEASE_BRANCH == "release" ] && echo 0) || ([ $FEATURE_BRANCH == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - - PATCH=$(([ $RELEASE_RC_BRANCH == "release-rc" ] && echo 0) || ([ $RELEASE_BRANCH == "release" ] && echo 0) || ([ $FEATURE_BRANCH == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - - RC_PREFIX=$([ $RELEASE_RC_BRANCH == "release-rc" ] && echo $((CURRENT_RC+1)) || echo '') - - echo $(([ $RELEASE_RC_BRANCH == "release-rc" ] && echo $MAJOR.$MINOR.$PATCH-rc.$RC_PREFIX) || echo $MAJOR.$MINOR.$PATCH) after_success: - cd src/OData.QueryBuilder && dotnet minicover instrument --workdir ../../coverage --parentdir ../ --assemblies test/**/bin/$CONFIGURATION/**/*.dll --sources src/**/*.cs && dotnet minicover reset --workdir ../../coverage && cd ../../ - dotnet test --no-build ./test/OData.QueryBuilder.Test @@ -39,13 +23,11 @@ before_deploy: - LAST_TAG=$(echo $(git describe --tags $(git rev-list --tags --max-count=1)) | cut -d'v' -f 2) - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - - CURRENT_PATCH=$(echo $LAST_TAG | cut -d. -f 3) - - CURRENT_RC=$(echo $LAST_TAG | cut -d. -f 4) - - RC=$([ "$(echo $PR_TITLE | grep -oP 'release-rc')" == "release-rc" ] && echo -rc.$((CURRENT_RC+1)) || echo '') - - MAJOR=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1))) || echo $CURRENT_MAJOR) - - MINOR=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - - PATCH=$(([ "$(echo $RC)" == "" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - - NEW_TAG=$(echo $MAJOR.$MINOR.$PATCH$RC) + - CURRENT_PATCH=$(echo $(echo $LAST_TAG | cut -d. -f 3) | cut -d- -f 1) + - MAJOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1)) || echo $CURRENT_MAJOR) + - MINOR=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) + - PATCH=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) + - NEW_TAG=$(echo $MAJOR.$MINOR.$PATCH) - PACKAGE_VERSION=${NEW_TAG:-$DEFAULT_PACKAGE_VERSION} - git tag v$PACKAGE_VERSION && git push origin v$PACKAGE_VERSION - dotnet pack -c $CONFIGURATION -p:PackageVersion=$PACKAGE_VERSION @@ -56,8 +38,6 @@ deploy: cleanup: true repo: ZEXSM/OData.QueryBuilder on: - branch: - - rc - - master + branch: master after_deploy: - dotnet nuget push ./src/OData.QueryBuilder/bin/Release/OData.QueryBuilder.$PACKAGE_VERSION.nupkg -k $NUGET_API_KEY -s $NUGET_SOURCE \ No newline at end of file From 67483f0ac1aaaca4a6dae084725092f128c60ae1 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 16:42:20 +0300 Subject: [PATCH 62/76] #ZEXSM#test --- test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs b/test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs index 685e63ed..912a9f4c 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs @@ -76,6 +76,7 @@ public void ODataQueryBuilderKey_ExpandNested_Select_Success() .Expand(ff => ff.For(s => s.ODataCode) .Select(s => s.IdCode)); f.For(s => s.ODataKindNew) + .Expand(ff => ff.ODataCode) .Select(s => s.IdKind); f.For(s => s.ODataKindNew) .Select(s => s.IdKind); @@ -83,7 +84,7 @@ public void ODataQueryBuilderKey_ExpandNested_Select_Success() .Select(s => new { s.IdType, s.Sum }) .ToUri(); - uri.OriginalString.Should().Be("http://mock/odata/ODataType(223123123)?$expand=ODataKind($expand=ODataCode($select=IdCode)),ODataKindNew($select=IdKind),ODataKindNew($select=IdKind)&$select=IdType,Sum"); + uri.OriginalString.Should().Be("http://mock/odata/ODataType(223123123)?$expand=ODataKind($expand=ODataCode($select=IdCode)),ODataKindNew($expand=ODataCode;$select=IdKind),ODataKindNew($select=IdKind)&$select=IdType,Sum"); } From f3e0abc6c5dea9122c06dd26d63a1560fe896cad Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 16:49:44 +0300 Subject: [PATCH 63/76] #ZEXSM#fix nuspec --- src/OData.QueryBuilder/OData.QueryBuilder.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OData.QueryBuilder/OData.QueryBuilder.nuspec b/src/OData.QueryBuilder/OData.QueryBuilder.nuspec index 34f44ae5..b2d8022b 100644 --- a/src/OData.QueryBuilder/OData.QueryBuilder.nuspec +++ b/src/OData.QueryBuilder/OData.QueryBuilder.nuspec @@ -16,6 +16,6 @@ odata, querybuilder, dotnet, charp - + \ No newline at end of file From 07d03d6b8aad18c9382ab1084a8faaa3160b7696 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 17:09:14 +0300 Subject: [PATCH 64/76] #ZEXSM#review nuspec --- .../OData.QueryBuilder.csproj | 22 ++++++++++++------- .../OData.QueryBuilder.nuspec | 21 ------------------ 2 files changed, 14 insertions(+), 29 deletions(-) delete mode 100644 src/OData.QueryBuilder/OData.QueryBuilder.nuspec diff --git a/src/OData.QueryBuilder/OData.QueryBuilder.csproj b/src/OData.QueryBuilder/OData.QueryBuilder.csproj index b9ec970a..04de3488 100644 --- a/src/OData.QueryBuilder/OData.QueryBuilder.csproj +++ b/src/OData.QueryBuilder/OData.QueryBuilder.csproj @@ -1,17 +1,23 @@  + true netstandard2.0 - bin\$(Configuration)\$(TargetFramework)\OData.QueryBuilder.nuspec - version=$(PackageVersion) - latest + OData.QueryBuilder + $(PackageVersion) + MIT + true + https://github.com/ZEXSM/OData.QueryBuilder + https://github.com/ZEXSM/OData.QueryBuilder + git + odata;querybuilder;dotnet;charp + ZEXSM + Library provides linq syntax and allows you to build OData queries based on the data model + 8.0 - - - Always - - + + diff --git a/src/OData.QueryBuilder/OData.QueryBuilder.nuspec b/src/OData.QueryBuilder/OData.QueryBuilder.nuspec deleted file mode 100644 index b2d8022b..00000000 --- a/src/OData.QueryBuilder/OData.QueryBuilder.nuspec +++ /dev/null @@ -1,21 +0,0 @@ - - - - OData.QueryBuilder - - 0.0.0 - Library provides linq syntax and allows you to build OData queries based on the data model - en-US - Borisov Zakhar - Borisov Zakhar - https://github.com/ZEXSM/OData.QueryBuilder - MIT - true - git - https://github.com/ZEXSM/OData.QueryBuilder - odata, querybuilder, dotnet, charp - - - - - \ No newline at end of file From 4b876f8f3b1ff51c2b1a4a14edfe4c4f532a415a Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Fri, 26 Jun 2020 23:13:45 +0300 Subject: [PATCH 65/76] #ZEXSM#review readme --- README.md | 237 ++++++++++++++++++++++++++---------------------------- 1 file changed, 114 insertions(+), 123 deletions(-) diff --git a/README.md b/README.md index 4a7b7a7b..4ac83591 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,9 @@ Library provides linq syntax and allows you to build OData queries based on the * Expression is not used to `Compile()`, which generates `MSIL` code, which leads to memory leaks * Support: * nested `OData` extenders with a choice of filtering - * `all`, `any` + * operators `all`, `any`, `in` * date functions `date` - * string functions `substringof`, `toupper` - * operator `in` + * string functions `contains`, `substringof`, `toupper`, `tolower` ## Installation To install `OData.QueryBuilder` from `Visual Studio`, find `OData.QueryBuilder` in the `NuGet` package manager user interface or enter the following command in the package manager console: @@ -71,7 +70,9 @@ dotnet add -v 1.0.0 OData.QueryBuilder odataQueryBuilder.ToUri() odataQueryBuilder.ToDictionary() ``` -## ByKey +## Fluent api + +#### ByKey ```csharp var uri = new ODataQueryBuilder("http://mock/odata") .For(s => s.ODataType) @@ -86,7 +87,7 @@ var uri = new ODataQueryBuilder("http://mock/odata") .ToUri() ``` > http://mock/odata/ODataType("223123123") -## ByList +#### ByList ```csharp var uri = new ODataQueryBuilder("http://mock/odata") .For(s => s.ODataType) @@ -94,7 +95,7 @@ var uri = new ODataQueryBuilder("http://mock/odata") .ToUri() ``` > http://mock/odata/ODataType -## Select +#### Select ```csharp .Select(s => s.Id) ``` @@ -103,7 +104,7 @@ var uri = new ODataQueryBuilder("http://mock/odata") .Select(s => new { s.Id, s.Sum, s.Type }) ``` > $select=Id,Sum,Type -## Expand +#### Expand ```csharp .Expand(s => s.BaseType) ``` @@ -113,131 +114,39 @@ var uri = new ODataQueryBuilder("http://mock/odata") ``` > $expand=BaseType,ODataKind ```csharp -.Expand(f => -{ - f.For(s => s.ODataKind) - .Expand(s=> s.For(s => s.ODataCode) +.Expand(f => f + .For(s => s.ODataKind) + .Expand(s=> s + .For(s => s.ODataCode) .Filter(s => s.IdKind == 1) + .OrderBy(s => s.IdKind) + .Top(1) .Select(s => s.IdCode)); - f.For(s => s.ODataKindNew) - .Select(s => s.IdKind); }) ``` -> $expand=ODataKind($expand=ODataCode($filter=IdKind eq 1;$select=IdCode)),ODataKindNew($select=IdKind) -## Filter -```csharp -.Filter(s => s.ODataKind.ODataCode.IdCode >= 3 || s.IdType == 5) -``` -> $filter=ODataKind/ODataCode/IdCode ge 3 or IdType eq 5 -```csharp -private static string IdCodeStatic => "testCode"; -... -var constValue = "3"; -.Filter(s => - s.ODataKind.ODataCode.Code == constValue || s.ODataKind.ODataCode.Code == "5" - && s.ODataKind.ODataCode.Code == IdCodeStatic) -``` -> $filter=ODataKind/ODataCode/Code eq '3' or ODataKind/ODataCode/Code eq '5' and ODataKind/ODataCode/Code eq 'testCode' -```csharp -.Filter(s => s.ODataKind.ODataCodes.Any(a => a.IdCode == 1) - && s.ODataKind.ODataCodes.All(v => v.IdActive)) -``` -> $filter=ODataKind/ODataCodes/any(a:a/IdCode eq 1) and ODataKind/ODataCodes/all(v:v/IdActive) -```csharp -var constValue = 2; -var constCurrentDate = DateTime.Today.ToString("yyyy-MM-dd"); - -.Filter(s => - (s.IdType < constValue && s.ODataKind.ODataCode.IdCode >= 3) - || s.IdType == 5 - && s.IdRule != default(int?) - && s.IdRule == null) -``` -> $filter=IdType lt 2 and ODataKind/ODataCode/IdCode ge 3 or IdType eq 5 and IdRule ne null and IdRule eq null -```csharp -var constCurrentDateToday = new DateTime(2019, 2, 9); -var constCurrentDateNow = new DateTime(2019, 2, 9, 1, 2, 4); -var newObject = new ODataTypeEntity { ODataKind = new ODataKindEntity { EndDate = constCurrentDateToday } }; - -.Filter(s => - s.ODataKind.OpenDate.Date == constCurrentDateNow - && s.ODataKind.OpenDate == constCurrentDateToday - && s.ODataKind.OpenDate == DateTime.Today - && s.Open.Date == DateTime.Today - && s.Open == DateTime.Today - && s.Open == constCurrentDateToday - && s.Open.Date == newObject.ODataKind.EndDate - && s.ODataKind.OpenDate.Date == new DateTime(2019, 7, 9) - && ((DateTime)s.BeginDate).Date == DateTime.Today) -``` -> $filter=date(ODataKind/OpenDate) eq 2019-02-09 and ODataKind/OpenDate eq 2019-02-09T00:00:00.0000000 and ODataKind/OpenDate eq 2019-08-18T00:00:00.0000000+03:00 and date(Open) eq 2019-08-18 and Open eq 2019-08-18T00:00:00.0000000+03:00 and Open eq 2019-02-09T00:00:00.0000000 and date(Open) eq 2019-02-09 and date(ODataKind/OpenDate) eq 2019-07-09 and date(BeginDate) eq 2019-08-18 -```csharp -var constStrIds = new[] { "123", "512" }; -var constStrListIds = new[] { "123", "512" }.ToList(); -var constIntIds = new[] { 123, 512 }; -var constIntListIds = new[] { 123, 512 }.ToList(); -var newObject = new ODataTypeEntity { ODataKind = new ODataKindEntity { Sequence = constIntListIds } }; -var newObjectSequenceArray = new ODataTypeEntity { ODataKind = new ODataKindEntity { SequenceArray = constIntIds } }; - -.Filter(s => constStrIds.Contains(s.ODataKind.ODataCode.Code) - && constStrListIds.Contains(s.ODataKind.ODataCode.Code) - && constIntIds.Contains(s.IdType) - && constIntListIds.Contains(s.IdType) - && constIntIds.Contains((int)s.IdRule) - && constIntListIds.Contains((int)s.IdRule) - && newObject.ODataKind.Sequence.Contains(s.ODataKind.IdKind) - && newObjectSequenceArray.ODataKind.SequenceArray.Contains(s.ODataKind.ODataCode.IdCode)) -``` -> $filter=ODataKind/ODataCode/Code in ('123','512') and ODataKind/ODataCode/Code in ('123','512') and IdType in (123,512) and IdType in (123,512) and IdRule in (123,512) and IdRule in (123,512) and ODataKind/IdKind in (123,512) and ODataKind/ODataCode/IdCode in (123,512) +> $expand=ODataKind($expand=ODataCode($filter=IdKind eq 1;$orderby=IdKind;$top=1;$select=IdCode)) +#### Filter ```csharp -var constStrIds = default(IEnumerable); -var constStrListIds = new string[] { }.ToList(); -var constIntIds = default(int[]); -var constIntListIds = new[] { 123, 512 }.ToList(); -var newObject = new ODataTypeEntity { ODataKind = new ODataKindEntity { Sequence = constIntListIds } }; -var newObjectSequenceArray = new ODataTypeEntity { ODataKind = new ODataKindEntity { SequenceArray = constIntIds } }; - -.Filter(s => constStrIds.Contains(s.ODataKind.ODataCode.Code) - && constStrListIds.Contains(s.ODataKind.ODataCode.Code) - && constIntIds.Contains(s.IdType) - && constIntListIds.Contains(s.IdType) - && constIntIds.Contains((int)s.IdRule) - && constIntListIds.Contains((int)s.IdRule) - && newObject.ODataKind.Sequence.Contains(s.ODataKind.IdKind) - && newObjectSequenceArray.ODataKind.SequenceArray.Contains(s.ODataKind.ODataCode.IdCode)) +.Filter(s => s.ODataKind.ODataCode.Code >= "test_code" || s.IdType >= 5) ``` -> $filter=IdType in (123,512) and IdRule in (123,512) and ODataKind/IdKind in (123,512) +> $filter=ODataKind/ODataCode/IdCode eq 'test_code' or IdType ge 5 ```csharp -.Filter(s => s.IsActive && s.IsOpen == true && s.ODataKind.ODataCode.IdActive == false) +.Filter(s => s.IdRule != default(int?) && s.IdRule == null) ``` -> $filter=IsActive and IsOpen eq true and ODataKind/ODataCode/IdActive eq false +> $filter=IdRule ne null and IdRule eq null ```csharp -var constStrIds = new[] { "123", "512" }; -var constValue = 3; - -.Filter(s => s.IdRule == constValue - && s.IsActive - && (((DateTimeOffset)s.EndDate).Date == default(DateTimeOffset?) || s.EndDate > DateTime.Today) - && (((DateTime)s.BeginDate).Date != default(DateTime?) || ((DateTime)s.BeginDate).Date <= DateTime.Today) - && constStrIds.Contains(s.ODataKind.ODataCode.Code)) +.Filter(s => s.ODataKind.OpenDate == DateTime.Today or s.ODataKind.OpenDate == new DateTime(2019, 7, 9)) or s.ODataKind.OpenDate == DateTime.Now) ``` -> $filter=IdRule eq 3 and IsActive and date(EndDate) eq null or EndDate gt 2019-08-18T00:00:00.0000000+03:00 and date(BeginDate) ne null or date(BeginDate) le 2019-08-18 and ODataKind/ODataCode/Code in ('123','512') +> $filter=ODataKind/OpenDate eq 2019-02-09T00:00:00Z or ODataKind/OpenDate eq 2019-02-09T00:00:00Z or ODataKind/OpenDate eq 2019-02-09T15:10:20Z ```csharp -.Filter(s => s.ODataKind.Color.ToString() == ColorEnum.Blue.ToString() - && s.ODataKind.Color == ColorEnum.Blue) +.Filter(s => s.IsActive && s.IsOpen == true && !s.ODataKind.ODataCode.IdActive) ``` -> $filter=ODataKind/Color eq 'Blue' and ODataKind/Color eq 2 +> $filter=IsActive and IsOpen eq true and not ODataKind/ODataCode/IdActive ```csharp -var constValue = "p".ToUpper(); -var newObject = new ODataTypeEntity { TypeCode = "TypeCodeValue".ToUpper() }; - -.Filter(s => s.ODataKind.ODataCode.Code.ToUpper().Contains("W") - || s.ODataKind.ODataCode.Code.Contains(constValue) - || s.ODataKindNew.ODataCode.Code.Contains(newObject.TypeCode) - || s.ODataKindNew.ODataCode.Code.Contains("55")) +.Filter(s => s.ODataKind.Color == ColorEnum.Blue) ``` -> $filter=substringof('W',toupper(ODataKind/ODataCode/Code)) or substringof('P',ODataKind/ODataCode/Code) or substringof('TYPECODEVALUE',ODataKindNew/ODataCode/Code) or substringof('55',ODataKindNew/ODataCode/Code) -## OrderBy +> $filter=ODataKind/Color eq 2 +#### OrderBy ```csharp .OrderBy(s => s.IdType) ``` @@ -246,7 +155,7 @@ var newObject = new ODataTypeEntity { TypeCode = "TypeCodeValue".ToUpper() }; .OrderBy(s => new { s.IdType, s.Sum }) ``` > $orderby=IdType,Sum asc -## OrderByDescending +#### OrderByDescending ```csharp .OrderByDescending(s => s.IdType) ``` @@ -255,7 +164,7 @@ var newObject = new ODataTypeEntity { TypeCode = "TypeCodeValue".ToUpper() }; .OrderByDescending(s => new { s.IdType, s.Sum }) ``` > $orderby=IdType,Sum desc -## Count +#### Count ```csharp .Count() ``` @@ -264,13 +173,95 @@ var newObject = new ODataTypeEntity { TypeCode = "TypeCodeValue".ToUpper() }; .Count(false) ``` > $count=false -## Skip +#### Skip ```csharp .Skip(12) ``` > $skip=12 -## Top +#### Top ```csharp .Top(100) ``` -> $top=100 \ No newline at end of file +> $top=100 + +## Usage operators + +#### In + +```csharp +.Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, new[] { "123", "512" }) && o.In(s.IdType, new[] { 123, 512 })) +``` +> $filter=ODataKind/ODataCode/Code in ('123','512') and IdType in (123,512) + +#### Any + +```csharp +.Filter((s, f, o) => o.Any(s.ODataKind.ODataCodes, v => v.IdCode == 1) +``` +> $filter=ODataKind/ODataCodes/any(v:v/IdCode eq 1) + +#### All + +```csharp +.Filter((s, f, o) => o.All(s.ODataKind.ODataCodes, v => v.IdActive)) +``` +> $filter=ODataKind/ODataCodes/all(v:v/IdActive) + +## Usage date functions + +#### Date + +```csharp +.Filter((s, f) => f.Date(s.Open) == DateTime.Today) +``` +> $filter=date(Open) eq 2019-02-09T00:00:00Z + +## Usage string functions + +#### Contains + +```csharp +.Filter((s, f) => f.Contains(s.ODataKind.ODataCode.Code, "W")) +``` +> $filter=contains(ODataKind/ODataCode/Code,'W') + +#### SubstringOf + +```csharp +.Filter((s, f) => f.SubstringOf("W", s.ODataKind.ODataCode.Code)) +``` +> $filter=substringof('W',ODataKind/ODataCode/Code) + +#### ToUpper + +```csharp +.Filter((s, f) => f.ToUpper(s.ODataKind.ODataCode.Code)) +``` +> $filter=toupper(ODataKind/ODataCode/Code) + +#### ToLower + +```csharp +.Filter((s, f) => f.ToLower(s.ODataKind.ODataCode.Code)) +``` +> $filter=tolower(ODataKind/ODataCode/Code) + +## Usage convert functions + +#### ConvertEnumToString +```csharp +.Filter((s, f) => s.ODataKind.Color == f.ConvertEnumToString(ColorEnum.Blue)) +``` +> $filter=ODataKind/Color eq 'Blue' + +#### ConvertDateTimeToString +```csharp +.Filter((s, f) => s.ODataKind.OpenDate == f.ConvertDateTimeToString(new DateTime(2019, 2, 9), "yyyy-MM-dd")) +``` +> $filter=ODataKind/OpenDate eq 2019-02-09 + +#### ConvertDateTimeOffsetToString +```csharp +.Filter((s, f) => s.ODataKind.OpenDate == f.ConvertDateTimeToString(new DateTimeOffset(new DateTime(2019, 2, 9)), "yyyy-MM-dd")) +``` +> $filter=ODataKind/OpenDate eq 2019-02-09 \ No newline at end of file From a09e5494882f67b00572bc175a6470c9728c78b1 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sat, 27 Jun 2020 14:16:10 +0300 Subject: [PATCH 66/76] #ZEXSM#readme#suppres exceptions default false --- README.md | 34 +++++++++++++++--- .../Options/ODataQueryBuilderOptions.cs | 4 +-- .../ODataQueryOptionListTest.cs | 36 +++++++++---------- 3 files changed, 49 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 4ac83591..19570e88 100644 --- a/README.md +++ b/README.md @@ -235,16 +235,16 @@ var uri = new ODataQueryBuilder("http://mock/odata") #### ToUpper ```csharp -.Filter((s, f) => f.ToUpper(s.ODataKind.ODataCode.Code)) +.Filter((s, f) => f.ToUpper(s.ODataKind.ODataCode.Code) == "TEST_CODE") ``` -> $filter=toupper(ODataKind/ODataCode/Code) +> $filter=toupper(ODataKind/ODataCode/Code) eq 'TEST_CODE' #### ToLower ```csharp -.Filter((s, f) => f.ToLower(s.ODataKind.ODataCode.Code)) +.Filter((s, f) => f.ToLower(s.ODataKind.ODataCode.Code) == "test_code") ``` -> $filter=tolower(ODataKind/ODataCode/Code) +> $filter=tolower(ODataKind/ODataCode/Code)) eq 'test_code' ## Usage convert functions @@ -264,4 +264,28 @@ var uri = new ODataQueryBuilder("http://mock/odata") ```csharp .Filter((s, f) => s.ODataKind.OpenDate == f.ConvertDateTimeToString(new DateTimeOffset(new DateTime(2019, 2, 9)), "yyyy-MM-dd")) ``` -> $filter=ODataKind/OpenDate eq 2019-02-09 \ No newline at end of file +> $filter=ODataKind/OpenDate eq 2019-02-09 + +## Suppress exceptions + +:warning: __May result in loss of control over the expected result.__ + +> Suppression of inclusion excludes the whole expression from the request + +By default, suppression of function and operator argument exceptions is disabled. To enable it, you must pass the configuration `ODataQueryBuilderOptions` when initializing the builder +with initialization of the `SuppressExceptionOfNullOrEmptyFunctionArgs` and` SuppressExceptionOfNullOrEmptyOperatorArgs` properties. + +```csharp +var builder = new ODataQueryBuilder("http://mock/odata", new ODataQueryBuilderOptions { + SuppressExceptionOfNullOrEmptyFunctionArgs = true, + SuppressExceptionOfNullOrEmptyOperatorArgs = true, +}); + +var uri = builder + .For(s => s.ODataType) + .ByList() + .Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, new string[0]) or o.In(s.ODataKind.ODataCode.Code, null) && o.In(s.IdType, new[] { 123, 512 })) + .ToUri() +``` +> http://mock/odata/ODataType?$filter=IdType in (123,512) +``` \ No newline at end of file diff --git a/src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs b/src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs index baa879a0..95613b7b 100644 --- a/src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs +++ b/src/OData.QueryBuilder/Options/ODataQueryBuilderOptions.cs @@ -2,7 +2,7 @@ { public class ODataQueryBuilderOptions { - public bool SuppressExceptionOfNullOrEmptyFunctionArgs { get; set; } = true; - public bool SuppressExceptionOfNullOrEmptyOperatorArgs { get; set; } = true; + public bool SuppressExceptionOfNullOrEmptyFunctionArgs { get; set; } = false; + public bool SuppressExceptionOfNullOrEmptyOperatorArgs { get; set; } = false; } } diff --git a/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs b/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs index ea11fa4b..effd424a 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs @@ -351,9 +351,13 @@ public void ODataQueryBuilderList_Test_Substringof_Simple() [Fact(DisplayName = "SubstringOf is null or empty value => Success")] public void ODataQueryBuilderList_Test_SubstringOf_is_null_or_empty_value_Success() { + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyFunctionArgs = true }; + var odataQueryBuilder = new ODataQueryBuilder( + _commonFixture.BaseUri, odataQueryBuilderOptions); + var constValue = "p".ToUpper(); var newObject = new ODataTypeEntity { TypeCode = string.Empty }; - var uri = _odataQueryBuilderDefault + var uri = odataQueryBuilder .For(s => s.ODataType) .ByList() .Filter((s, f) => @@ -373,11 +377,7 @@ public void ODataQueryBuilderList_Test_Substringof_is_null_or_empty_value_Argume var constValue = default(string); var newObject = new ODataTypeEntity { TypeCode = string.Empty }; - var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyFunctionArgs = false }; - var odataQueryBuilder = new ODataQueryBuilder( - _commonFixture.BaseUri, odataQueryBuilderOptions); - - odataQueryBuilder.Invoking( + _odataQueryBuilderDefault.Invoking( (r) => r .For(s => s.ODataType) .ByList() @@ -414,11 +414,7 @@ public void ODataQueryBuilderList_Test_Contains_is_null_or_empty_value_ArgumentE var constValue = default(string); var newObject = new ODataTypeEntity { TypeCode = string.Empty }; - var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyFunctionArgs = false }; - var odataQueryBuilder = new ODataQueryBuilder( - _commonFixture.BaseUri, odataQueryBuilderOptions); - - odataQueryBuilder.Invoking( + _odataQueryBuilderDefault.Invoking( (r) => r .For(s => s.ODataType) .ByList() @@ -434,9 +430,13 @@ public void ODataQueryBuilderList_Test_Contains_is_null_or_empty_value_ArgumentE [Fact(DisplayName = "Contains is null or empty value => Success")] public void ODataQueryBuilderList_Test_Contains_is_null_or_empty_value_Success() { + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyFunctionArgs = true }; + var odataQueryBuilder = new ODataQueryBuilder( + _commonFixture.BaseUri, odataQueryBuilderOptions); + var constValue = "P"; var newObject = new ODataTypeEntity { TypeCode = string.Empty }; - var uri = _odataQueryBuilderDefault + var uri = odataQueryBuilder .For(s => s.ODataType) .ByList() .Filter((s, f) => @@ -479,6 +479,10 @@ public void ODataQueryBuilderList_Operator_In_Success() [Fact(DisplayName = "(ODataQueryBuilderList) Operator IN empty => Success")] public void ODataQueryBuilderList_Operator_In_Empty_Success() { + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArgs = true }; + var odataQueryBuilder = new ODataQueryBuilder( + _commonFixture.BaseUri, odataQueryBuilderOptions); + var constStrIds = default(IEnumerable); var constEmprtyStrListIds = new string[] { }.ToList(); var constIntIds = default(int[]); @@ -487,7 +491,7 @@ public void ODataQueryBuilderList_Operator_In_Empty_Success() var newObject = new ODataTypeEntity { ODataKind = new ODataKindEntity { Sequence = constIntListIds } }; var newObjectSequenceArray = new ODataTypeEntity { ODataKind = new ODataKindEntity { SequenceArray = constIntIds } }; - var uri = _odataQueryBuilderDefault + var uri = odataQueryBuilder .For(s => s.ODataType) .ByList() .Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, constStrIds) @@ -509,11 +513,7 @@ public void ODataQueryBuilderList_Operator_In_is_null_1() { var constEmprtyStrListIds = new string[] { }.ToList(); - var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyOperatorArgs = false }; - var odataQueryBuilder = new ODataQueryBuilder( - _commonFixture.BaseUri, odataQueryBuilderOptions); - - odataQueryBuilder.Invoking( + _odataQueryBuilderDefault.Invoking( (r) => r .For(s => s.ODataType) .ByList() From f071e4a3e4e024b5663079a0dbc3d6380d456f4f Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sat, 27 Jun 2020 14:22:36 +0300 Subject: [PATCH 67/76] #ZEXSM#fix readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 19570e88..f5013a61 100644 --- a/README.md +++ b/README.md @@ -284,7 +284,9 @@ var builder = new ODataQueryBuilder("http://mock/odata", new var uri = builder .For(s => s.ODataType) .ByList() - .Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, new string[0]) or o.In(s.ODataKind.ODataCode.Code, null) && o.In(s.IdType, new[] { 123, 512 })) + .Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, new string[0]) or o.In(s.ODataKind.ODataCode.Code, null) + && f.Contains(s.ODataKind.ODataCode.Code, default(string)) + && o.In(s.IdType, new[] { 123, 512 })) .ToUri() ``` > http://mock/odata/ODataType?$filter=IdType in (123,512) From 3540963b042b83f1c3778bd823950d858b88512b Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sun, 26 Jul 2020 18:48:43 +0300 Subject: [PATCH 68/76] #ZEXSM#add support concat function#bugfix lambda any/all of array --- .../Constants/ODataFunctionNames.cs | 15 -- .../Constants/ODataOperatorNames.cs | 11 -- .../Conventions/Functions/IODataFunction.cs | 2 +- ...s => IODataStringAndCollectionFunction.cs} | 10 +- .../Visitors/VisitorExpression.cs | 56 ++++++-- .../Fakes/ODataTypeEntity.cs | 2 + .../ODataQueryOptionListTest.cs | 131 ++++++++++++++++++ 7 files changed, 187 insertions(+), 40 deletions(-) delete mode 100644 src/OData.QueryBuilder/Conventions/Constants/ODataFunctionNames.cs delete mode 100644 src/OData.QueryBuilder/Conventions/Constants/ODataOperatorNames.cs rename src/OData.QueryBuilder/Conventions/Functions/{IODataStringFunction.cs => IODataStringAndCollectionFunction.cs} (63%) diff --git a/src/OData.QueryBuilder/Conventions/Constants/ODataFunctionNames.cs b/src/OData.QueryBuilder/Conventions/Constants/ODataFunctionNames.cs deleted file mode 100644 index 7d8698c3..00000000 --- a/src/OData.QueryBuilder/Conventions/Constants/ODataFunctionNames.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace OData.QueryBuilder.Conventions.Constants -{ - internal struct ODataFunctionNames - { - public const string Date = "date"; - - public const string SubstringOf = "substringof"; - - public const string Contains = "contains"; - - public const string ToUpper = "toupper"; - - public const string ToLower = "tolower"; - } -} diff --git a/src/OData.QueryBuilder/Conventions/Constants/ODataOperatorNames.cs b/src/OData.QueryBuilder/Conventions/Constants/ODataOperatorNames.cs deleted file mode 100644 index 7d4a43f0..00000000 --- a/src/OData.QueryBuilder/Conventions/Constants/ODataOperatorNames.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace OData.QueryBuilder.Conventions.Constants -{ - internal struct ODataOperatorNames - { - public const string Any = "any"; - - public const string All = "all"; - - public const string In = "in"; - } -} diff --git a/src/OData.QueryBuilder/Conventions/Functions/IODataFunction.cs b/src/OData.QueryBuilder/Conventions/Functions/IODataFunction.cs index 892a4167..fa2b396e 100644 --- a/src/OData.QueryBuilder/Conventions/Functions/IODataFunction.cs +++ b/src/OData.QueryBuilder/Conventions/Functions/IODataFunction.cs @@ -1,6 +1,6 @@ namespace OData.QueryBuilder.Conventions.Functions { - public interface IODataFunction : IODataStringFunction, IODataDateFunction, IConvertFunction + public interface IODataFunction : IODataStringAndCollectionFunction, IODataDateFunction, IConvertFunction { } } diff --git a/src/OData.QueryBuilder/Conventions/Functions/IODataStringFunction.cs b/src/OData.QueryBuilder/Conventions/Functions/IODataStringAndCollectionFunction.cs similarity index 63% rename from src/OData.QueryBuilder/Conventions/Functions/IODataStringFunction.cs rename to src/OData.QueryBuilder/Conventions/Functions/IODataStringAndCollectionFunction.cs index 37d31370..d785b7a5 100644 --- a/src/OData.QueryBuilder/Conventions/Functions/IODataStringFunction.cs +++ b/src/OData.QueryBuilder/Conventions/Functions/IODataStringAndCollectionFunction.cs @@ -1,6 +1,9 @@ namespace OData.QueryBuilder.Conventions.Functions { - public interface IODataStringFunction + /// + /// http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_StringandCollectionFunctions + /// + public interface IODataStringAndCollectionFunction { bool SubstringOf(string value, string columnName); @@ -18,5 +21,10 @@ public interface IODataStringFunction /// http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_tolower /// string ToLower(string columnName); + + /// + /// http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_concat + /// + string Concat(string s1, string s2); } } diff --git a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs index 41c38f0c..dee2c2b1 100644 --- a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs +++ b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs @@ -24,6 +24,7 @@ public VisitorExpression(ODataQueryBuilderOptions odataQueryBuilderOptions) => NewExpression newExpression => VisitNewExpression(newExpression), UnaryExpression unaryExpression => VisitUnaryExpression(unaryExpression), LambdaExpression lambdaExpression => VisitLambdaExpression(lambdaExpression), + ParameterExpression parameterExpression => VisitParameterExpression(parameterExpression), _ => default, }; @@ -71,21 +72,21 @@ protected virtual string VisitMethodCallExpression(MethodCallExpression methodCa return default; } - return $"{in0} {ODataOperatorNames.In} ({in1})"; + return $"{in0} {nameof(IODataOperator.In).ToLower()} ({in1})"; case nameof(IODataOperator.All): var all0 = VisitExpression(methodCallExpression.Arguments[0]); var all1 = VisitExpression(methodCallExpression.Arguments[1]); - return $"{all0}/{ODataOperatorNames.All}({all1})"; + return $"{all0}/{nameof(IODataOperator.All).ToLower()}({all1})"; case nameof(IODataOperator.Any): var any0 = VisitExpression(methodCallExpression.Arguments[0]); var any1 = VisitExpression(methodCallExpression.Arguments[1]); - return $"{any0}/{ODataOperatorNames.Any}({any1})"; + return $"{any0}/{nameof(IODataOperator.Any).ToLower()}({any1})"; case nameof(IODataFunction.Date): var date0 = VisitExpression(methodCallExpression.Arguments[0]); - return $"{ODataFunctionNames.Date}({date0})"; + return $"{nameof(IODataFunction.Date).ToLower()}({date0})"; case nameof(IODataFunction.SubstringOf): var substringOf0 = ReflectionExtensions.ConvertToString(GetValueOfExpression(methodCallExpression.Arguments[0])); var substringOf1 = VisitExpression(methodCallExpression.Arguments[1]); @@ -100,7 +101,7 @@ protected virtual string VisitMethodCallExpression(MethodCallExpression methodCa return default; } - return $"{ODataFunctionNames.SubstringOf}({substringOf0},{substringOf1})"; + return $"{nameof(IODataFunction.SubstringOf).ToLower()}({substringOf0},{substringOf1})"; case nameof(IODataFunction.Contains): var contains0 = VisitExpression(methodCallExpression.Arguments[0]); var contains1 = ReflectionExtensions.ConvertToString(GetValueOfExpression(methodCallExpression.Arguments[1])); @@ -115,15 +116,30 @@ protected virtual string VisitMethodCallExpression(MethodCallExpression methodCa return default; } - return $"{ODataFunctionNames.Contains}({contains0},{contains1})"; - case nameof(IODataStringFunction.ToUpper): + return $"{nameof(IODataFunction.Contains).ToLower()}({contains0},{contains1})"; + case nameof(IODataFunction.Concat): + var concat0 = VisitExpression(methodCallExpression.Arguments[0]); + var concat1 = VisitExpression(methodCallExpression.Arguments[1]); + + if (concat0.IsNullOrQuotes() || concat1.IsNullOrQuotes()) + { + if (!_odataQueryBuilderOptions.SuppressExceptionOfNullOrEmptyFunctionArgs) + { + throw new ArgumentException("Value is empty or null"); + } + + return default; + } + + return $"{nameof(IODataFunction.Concat).ToLower()}({concat0},{concat1})"; + case nameof(IODataStringAndCollectionFunction.ToUpper): var toUpper0 = VisitExpression(methodCallExpression.Arguments[0]); - return $"{ODataFunctionNames.ToUpper}({toUpper0})"; - case nameof(IODataStringFunction.ToLower): + return $"{nameof(IODataFunction.ToUpper).ToLower()}({toUpper0})"; + case nameof(IODataStringAndCollectionFunction.ToLower): var toLower0 = VisitExpression(methodCallExpression.Arguments[0]); - return $"{ODataFunctionNames.ToLower}({toLower0})"; + return $"{nameof(IODataFunction.ToLower).ToLower()}({toLower0})"; case nameof(IConvertFunction.ConvertEnumToString): return $"'{GetValueOfExpression(methodCallExpression.Arguments[0])}'"; case nameof(IConvertFunction.ConvertDateTimeToString): @@ -180,10 +196,26 @@ protected virtual string VisitUnaryExpression(UnaryExpression unaryExpression) protected virtual string VisitLambdaExpression(LambdaExpression lambdaExpression) { - var tag = lambdaExpression.Parameters[0]?.Name; + var parameter = VisitParameterExpression(lambdaExpression.Parameters[0]); var filter = VisitExpression(lambdaExpression.Body); - return $"{tag}:{tag}/{filter}"; + if (parameter == null) + { + parameter = lambdaExpression.Parameters[0].Name; + return $"{parameter}:{parameter}/{filter}"; + } + + return $"{parameter}:{filter}"; + } + + protected virtual string VisitParameterExpression(ParameterExpression parameterExpression) + { + if (parameterExpression.Type == typeof(int) || parameterExpression.Type == typeof(string)) + { + return parameterExpression.Name; + } + + return default; } protected object GetValueOfExpression(Expression expression) => expression switch diff --git a/test/OData.QueryBuilder.Test/Fakes/ODataTypeEntity.cs b/test/OData.QueryBuilder.Test/Fakes/ODataTypeEntity.cs index 5521c926..5e09faff 100644 --- a/test/OData.QueryBuilder.Test/Fakes/ODataTypeEntity.cs +++ b/test/OData.QueryBuilder.Test/Fakes/ODataTypeEntity.cs @@ -27,6 +27,8 @@ public class ODataTypeEntity public ODataKindEntity ODataKind { get; set; } public ODataKindEntity ODataKindNew { get; set; } + + public string[] Tags { get; set; } } } diff --git a/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs b/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs index effd424a..9ccd40bf 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs @@ -209,6 +209,18 @@ public void ODataQueryBuilderList_Filter_All_Any_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=ODataKind/ODataCodes/any(v:v/IdCode eq 1) and ODataKind/ODataCodes/all(v:v/IdActive)"); } + [Fact(DisplayName = "(ODataQueryBuilderList) Filter Any => Success")] + public void ODataQueryBuilderList_Filter_Any_Success1() + { + var uri = _odataQueryBuilderDefault + .For(s => s.ODataType) + .ByList() + .Filter((s, f, o) => o.Any(s.Tags, t => t == "testTag")) + .ToUri(); + + uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=Tags/any(t:t eq 'testTag')"); + } + [Fact(DisplayName = "Expand,Filter,Select,OrderBy,OrderByDescending,Skip,Top,Count => Success")] public void ODataQueryBuilderList_Expand_Filter_Select_OrderBy_OrderByDescending_Skip_Top_Count_Success() { @@ -449,6 +461,125 @@ public void ODataQueryBuilderList_Test_Contains_is_null_or_empty_value_Success() uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=contains(ODataKind/ODataCode/Code,'P')"); } + [Fact(DisplayName = "Concat string simple => Success")] + public void ODataQueryBuilderList_concat_string_simple_success() + { + var uri = _odataQueryBuilderDefault + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => f.Concat(s.TypeCode, ";") == "typeCodeTest;") + .ToUri(); + + uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=concat(TypeCode,';') eq 'typeCodeTest;'"); + } + + [Fact(DisplayName = "Nested Concat string => Success")] + public void ODataQueryBuilderList_nested_concat_string_simple_success1() + { + var uri = _odataQueryBuilderDefault + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => f.Concat(f.Concat(s.TypeCode, ", "), s.ODataKind.ODataCode.Code) == "testTypeCode1, testTypeCode2") + .ToUri(); + + uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=concat(concat(TypeCode,', '),ODataKind/ODataCode/Code) eq 'testTypeCode1, testTypeCode2'"); + } + + [Fact(DisplayName = "Nested Concat string => Success")] + public void ODataQueryBuilderList_nested_concat_string_simple_success2() + { + var constParam = ", "; + + var uri = _odataQueryBuilderDefault + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => f.Concat(f.Concat(s.TypeCode, constParam), s.ODataKind.ODataCode.Code) == "testTypeCode1, testTypeCode2") + .ToUri(); + + uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=concat(concat(TypeCode,', '),ODataKind/ODataCode/Code) eq 'testTypeCode1, testTypeCode2'"); + } + + [Fact(DisplayName = "Nested Concat string => Success")] + public void ODataQueryBuilderList_nested_concat_string_simple_success3() + { + var constParam = ", "; + var constParamObject = new ODataTypeEntity { ODataKind = new ODataKindEntity { ODataCode = new ODataCodeEntity { Code = constParam } } }; + + var uri = _odataQueryBuilderDefault + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => f.Concat(f.Concat(s.TypeCode, constParamObject.ODataKind.ODataCode.Code), s.ODataKind.ODataCode.Code) == "testTypeCode1, testTypeCode2") + .ToUri(); + + uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=concat(concat(TypeCode,', '),ODataKind/ODataCode/Code) eq 'testTypeCode1, testTypeCode2'"); + } + + [Fact(DisplayName = "Concat string is null or empty value argument1 => Exception")] + public void ODataQueryBuilderList_concat_string_simple_argument1_exception() + { + var constValue = default(string); + var newObject = new ODataTypeEntity { TypeCode = string.Empty }; + + _odataQueryBuilderDefault.Invoking( + (r) => r + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => f.Concat(s.TypeCode, constValue) == "typeCodeTest;") + .ToUri()) + .Should().Throw().WithMessage("Value is empty or null"); + } + + [Fact(DisplayName = "Concat string is null or empty value argument2 => Exception")] + public void ODataQueryBuilderList_concat_string_simple_argument2_exception() + { + var constValue = default(string); + var newObject = new ODataTypeEntity { TypeCode = string.Empty }; + + _odataQueryBuilderDefault.Invoking( + (r) => r + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => f.Concat(constValue, s.TypeCode) == "typeCodeTest;") + .ToUri()) + .Should().Throw().WithMessage("Value is empty or null"); + } + + [Theory(DisplayName = "Concat is null empty value agr1 => Success")] + [InlineData("")] + [InlineData(null)] + public void ODataQueryBuilderList_concat_is_null_or_empty_value_agr1_success(string value) + { + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyFunctionArgs = true }; + var odataQueryBuilder = new ODataQueryBuilder( + _commonFixture.BaseUri, odataQueryBuilderOptions); + + var uri = odataQueryBuilder + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => f.Concat(value, s.TypeCode) == "typeCodeTest;") + .ToUri(); + + uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter='typeCodeTest;'"); + } + + [Theory(DisplayName = "Concat is null empty value agr2 => Success")] + [InlineData("")] + [InlineData(null)] + public void ODataQueryBuilderList_concat_is_null_or_empty_value_agr2_success(string value) + { + var odataQueryBuilderOptions = new ODataQueryBuilderOptions { SuppressExceptionOfNullOrEmptyFunctionArgs = true }; + var odataQueryBuilder = new ODataQueryBuilder( + _commonFixture.BaseUri, odataQueryBuilderOptions); + + var uri = odataQueryBuilder + .For(s => s.ODataType) + .ByList() + .Filter((s, f) => f.Concat(s.TypeCode, value) == "typeCodeTest;") + .ToUri(); + + uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter='typeCodeTest;'"); + } + [Fact(DisplayName = "Operator IN => Success")] public void ODataQueryBuilderList_Operator_In_Success() { From 9c5560a53881aaef52b78cecc919eb65baa855f8 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sun, 26 Jul 2020 18:57:35 +0300 Subject: [PATCH 69/76] #ZEX#review readme --- README.md | 84 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index f5013a61..f6603174 100644 --- a/README.md +++ b/README.md @@ -44,27 +44,27 @@ dotnet add -v 1.0.0 OData.QueryBuilder The builder allows you to build queries on the key and the list: * [ByKey](#ByKey) - * [Expand](#Expand) - * [Filter](#Filter) - * [Select](#Select) - * [OrderBy](#OrderBy) - * [OrderByDescending](#OrderByDescending) - * [Top](#Top) - * [Select](#Select) + * [expand](#expand) + * [filter](#filter) + * [select](#select) + * [orderby](#orderby) + * [orderby desc](#orderbydesc) + * [top](#top) + * [select](#select) * [ByList](#ByList) - * [Expand](#Expand) - * [Filter](#Filter) - * [Select](#Select) - * [OrderBy](#OrderBy) - * [OrderByDescending](#OrderByDescending) - * [Top](#Top) - * [Filter](#Filter) - * [Select](#Select) - * [OrderBy](#OrderBy) - * [OrderByDescending](#OrderByDescending) - * [Top](#Top) - * [Skip](#Skip) - * [Count](#Count) + * [expand](#expand) + * [filter](#filter) + * [select](#select) + * [orderby](#orderby) + * [orderby desc](#orderbydesc) + * [top](#top) + * [filter](#filter) + * [select](#select) + * [orderby](#orderby) + * [orderby desc](#orderby desc) + * [top](#top) + * [skip](#skip) + * [count](#count) 4. Get Uri request or collection of operators from the builder ```csharp odataQueryBuilder.ToUri() @@ -95,7 +95,10 @@ var uri = new ODataQueryBuilder("http://mock/odata") .ToUri() ``` > http://mock/odata/ODataType -#### Select + +## Usage options + +#### select ```csharp .Select(s => s.Id) ``` @@ -104,7 +107,7 @@ var uri = new ODataQueryBuilder("http://mock/odata") .Select(s => new { s.Id, s.Sum, s.Type }) ``` > $select=Id,Sum,Type -#### Expand +#### expand ```csharp .Expand(s => s.BaseType) ``` @@ -125,7 +128,7 @@ var uri = new ODataQueryBuilder("http://mock/odata") }) ``` > $expand=ODataKind($expand=ODataCode($filter=IdKind eq 1;$orderby=IdKind;$top=1;$select=IdCode)) -#### Filter +#### filter ```csharp .Filter(s => s.ODataKind.ODataCode.Code >= "test_code" || s.IdType >= 5) ``` @@ -146,7 +149,7 @@ var uri = new ODataQueryBuilder("http://mock/odata") .Filter(s => s.ODataKind.Color == ColorEnum.Blue) ``` > $filter=ODataKind/Color eq 2 -#### OrderBy +#### orderby ```csharp .OrderBy(s => s.IdType) ``` @@ -155,7 +158,7 @@ var uri = new ODataQueryBuilder("http://mock/odata") .OrderBy(s => new { s.IdType, s.Sum }) ``` > $orderby=IdType,Sum asc -#### OrderByDescending +#### orderby desc ```csharp .OrderByDescending(s => s.IdType) ``` @@ -164,7 +167,7 @@ var uri = new ODataQueryBuilder("http://mock/odata") .OrderByDescending(s => new { s.IdType, s.Sum }) ``` > $orderby=IdType,Sum desc -#### Count +#### count ```csharp .Count() ``` @@ -173,12 +176,12 @@ var uri = new ODataQueryBuilder("http://mock/odata") .Count(false) ``` > $count=false -#### Skip +#### skip ```csharp .Skip(12) ``` > $skip=12 -#### Top +#### top ```csharp .Top(100) ``` @@ -186,21 +189,21 @@ var uri = new ODataQueryBuilder("http://mock/odata") ## Usage operators -#### In +#### in ```csharp .Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, new[] { "123", "512" }) && o.In(s.IdType, new[] { 123, 512 })) ``` > $filter=ODataKind/ODataCode/Code in ('123','512') and IdType in (123,512) -#### Any +#### any ```csharp .Filter((s, f, o) => o.Any(s.ODataKind.ODataCodes, v => v.IdCode == 1) ``` > $filter=ODataKind/ODataCodes/any(v:v/IdCode eq 1) -#### All +#### all ```csharp .Filter((s, f, o) => o.All(s.ODataKind.ODataCodes, v => v.IdActive)) @@ -209,7 +212,7 @@ var uri = new ODataQueryBuilder("http://mock/odata") ## Usage date functions -#### Date +#### date ```csharp .Filter((s, f) => f.Date(s.Open) == DateTime.Today) @@ -218,33 +221,40 @@ var uri = new ODataQueryBuilder("http://mock/odata") ## Usage string functions -#### Contains +#### contains ```csharp .Filter((s, f) => f.Contains(s.ODataKind.ODataCode.Code, "W")) ``` > $filter=contains(ODataKind/ODataCode/Code,'W') -#### SubstringOf +#### substringof ```csharp .Filter((s, f) => f.SubstringOf("W", s.ODataKind.ODataCode.Code)) ``` > $filter=substringof('W',ODataKind/ODataCode/Code) -#### ToUpper +#### toupper ```csharp .Filter((s, f) => f.ToUpper(s.ODataKind.ODataCode.Code) == "TEST_CODE") ``` > $filter=toupper(ODataKind/ODataCode/Code) eq 'TEST_CODE' -#### ToLower +#### tolower ```csharp .Filter((s, f) => f.ToLower(s.ODataKind.ODataCode.Code) == "test_code") ``` -> $filter=tolower(ODataKind/ODataCode/Code)) eq 'test_code' +> $filter=tolower(ODataKind/ODataCode/Code) eq 'test_code' + +#### concat + +```csharp +.Filter((s, f) => f.Concat(s.ODataKind.ODataCode.Code, "_1") == "test_code_1") +``` +> $filter=concat(ODataKind/ODataCode/Code, '_1') eq 'test_code_1' ## Usage convert functions From 528b4828c13c753ab71f1ce9fe09ac377795b37d Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sun, 26 Jul 2020 19:13:32 +0300 Subject: [PATCH 70/76] #ZEXSM#fix readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f6603174..891c64f9 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ dotnet add -v 1.0.0 OData.QueryBuilder * [filter](#filter) * [select](#select) * [orderby](#orderby) - * [orderby desc](#orderby desc) + * [orderby desc](#orderbydesc) * [top](#top) * [skip](#skip) * [count](#count) From 0c722feb3aa8f4a39f2b5d4f6a590d0868b03d48 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sat, 1 Aug 2020 11:17:58 +0300 Subject: [PATCH 71/76] #ZEXSM#rename#internal --- .../IODataQueryExpandNestedBuilder.cs | 11 ++++++++++ .../Builders/IODataQueryNestedBuilder.cs | 11 ---------- .../Builders/ODataQueryBuilder.cs | 11 ++++++---- ...er.cs => ODataQueryExpandNestedBuilder.cs} | 20 +++++++++---------- .../Conventions/Options/IODataOptionKey.cs | 2 +- .../Conventions/Options/IODataOptionList.cs | 2 +- .../Options/Nested/IODataOptionNested.cs | 2 +- .../Options/Nested/ODataOptionNested.cs | 12 ++++++----- .../Options/Nested/ODataOptionNestedBase.cs} | 6 +++--- .../Conventions/Options/ODataOption.cs | 6 +++--- .../Conventions/Options/ODataOptionKey.cs | 8 ++++---- .../Conventions/Options/ODataOptionList.cs | 9 +++++---- src/OData.QueryBuilder/ODataQuery.cs | 2 +- .../ODataQueryOptionKeyTest.cs | 5 +++-- 14 files changed, 57 insertions(+), 50 deletions(-) create mode 100644 src/OData.QueryBuilder/Builders/IODataQueryExpandNestedBuilder.cs delete mode 100644 src/OData.QueryBuilder/Builders/IODataQueryNestedBuilder.cs rename src/OData.QueryBuilder/Builders/{ODataQueryNestedBuilder.cs => ODataQueryExpandNestedBuilder.cs} (58%) rename src/OData.QueryBuilder/{ODataQueryNested.cs => Conventions/Options/Nested/ODataOptionNestedBase.cs} (69%) diff --git a/src/OData.QueryBuilder/Builders/IODataQueryExpandNestedBuilder.cs b/src/OData.QueryBuilder/Builders/IODataQueryExpandNestedBuilder.cs new file mode 100644 index 00000000..fd06ace5 --- /dev/null +++ b/src/OData.QueryBuilder/Builders/IODataQueryExpandNestedBuilder.cs @@ -0,0 +1,11 @@ +using OData.QueryBuilder.Conventions.Options.Nested; +using System; +using System.Linq.Expressions; + +namespace OData.QueryBuilder.Builders +{ + public interface IODataQueryExpandNestedBuilder + { + IODataOptionNested For(Expression> nestedEntityExpand); + } +} diff --git a/src/OData.QueryBuilder/Builders/IODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/IODataQueryNestedBuilder.cs deleted file mode 100644 index 784d6d8e..00000000 --- a/src/OData.QueryBuilder/Builders/IODataQueryNestedBuilder.cs +++ /dev/null @@ -1,11 +0,0 @@ -using OData.QueryBuilder.Conventions.Options.Nested; -using System; -using System.Linq.Expressions; - -namespace OData.QueryBuilder.Builders -{ - public interface IODataQueryNestedBuilder - { - IODataOptionNested For(Expression> nestedEntityExpand); - } -} diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index 57b81693..8235e326 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -4,6 +4,7 @@ using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; +using System.Text; namespace OData.QueryBuilder.Builders { @@ -11,18 +12,18 @@ public class ODataQueryBuilder : IODataQueryBuilder { internal readonly VisitorExpression _visitorExpression; private readonly ODataQueryBuilderOptions _odataQueryBuilderOptions; - private readonly string _baseUrl; + private readonly StringBuilder _stringBuilder; public ODataQueryBuilder(Uri baseUrl, ODataQueryBuilderOptions odataQueryBuilderOptions = default) { - _baseUrl = $"{baseUrl.OriginalString.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"; + _stringBuilder =new StringBuilder($"{baseUrl.OriginalString.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"); _odataQueryBuilderOptions = odataQueryBuilderOptions ?? new ODataQueryBuilderOptions(); _visitorExpression = new VisitorExpression(_odataQueryBuilderOptions); } public ODataQueryBuilder(string baseUrl, ODataQueryBuilderOptions odataQueryBuilderOptions = default) { - _baseUrl = $"{baseUrl.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"; + _stringBuilder = new StringBuilder($"{baseUrl.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"); _odataQueryBuilderOptions = odataQueryBuilderOptions ?? new ODataQueryBuilderOptions(); _visitorExpression = new VisitorExpression(_odataQueryBuilderOptions); } @@ -31,7 +32,9 @@ public IODataOption For(Expression> en { var query = _visitorExpression.ToString(entityResource.Body); - return new ODataOption($"{_baseUrl}{query}", _odataQueryBuilderOptions); + _stringBuilder.Append(query); + + return new ODataOption(_stringBuilder, _odataQueryBuilderOptions); } } } \ No newline at end of file diff --git a/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryExpandNestedBuilder.cs similarity index 58% rename from src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs rename to src/OData.QueryBuilder/Builders/ODataQueryExpandNestedBuilder.cs index 44bbdfb0..bec5e32c 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryNestedBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryExpandNestedBuilder.cs @@ -7,29 +7,29 @@ namespace OData.QueryBuilder.Builders { - public class ODataQueryNestedBuilder : IODataQueryNestedBuilder + internal class ODataQueryExpandNestedBuilder : IODataQueryExpandNestedBuilder { private readonly ODataQueryBuilderOptions _odataQueryBuilderOptions; private readonly StringBuilder _stringBuilder; - private ODataQueryNested _odataQueryNested; - internal readonly VisitorExpression _visitorExpression; + private ODataOptionNestedBase _odataOptionNestedBase; + private readonly VisitorExpression _visitorExpression; - public ODataQueryNestedBuilder(ODataQueryBuilderOptions odataQueryBuilderOptions) + public string Query => $"{_stringBuilder}({_odataOptionNestedBase.Query})"; + + public ODataQueryExpandNestedBuilder(ODataQueryBuilderOptions odataQueryBuilderOptions) { _stringBuilder = new StringBuilder(); _odataQueryBuilderOptions = odataQueryBuilderOptions; _visitorExpression = new VisitorExpression(_odataQueryBuilderOptions); } - public string Query => $"{_stringBuilder}({_odataQueryNested.Query})"; - public IODataOptionNested For(Expression> nestedEntityExpand) { - if (!string.IsNullOrEmpty(_odataQueryNested?.Query)) + if (!string.IsNullOrEmpty(_odataOptionNestedBase?.Query)) { var query = _visitorExpression.ToString(nestedEntityExpand.Body); - _stringBuilder.Append($"({_odataQueryNested.Query}),{query}"); + _stringBuilder.Append($"({_odataOptionNestedBase.Query}),{query}"); } else { @@ -38,9 +38,9 @@ public IODataOptionNested For(Expression(_odataQueryBuilderOptions); + _odataOptionNestedBase = new ODataOptionNested(_odataQueryBuilderOptions); - return _odataQueryNested as ODataOptionNested; + return _odataOptionNestedBase as ODataOptionNested; } } } diff --git a/src/OData.QueryBuilder/Conventions/Options/IODataOptionKey.cs b/src/OData.QueryBuilder/Conventions/Options/IODataOptionKey.cs index 78c48980..747d2be3 100644 --- a/src/OData.QueryBuilder/Conventions/Options/IODataOptionKey.cs +++ b/src/OData.QueryBuilder/Conventions/Options/IODataOptionKey.cs @@ -8,7 +8,7 @@ public interface IODataOptionKey : IODataQuery { IODataOptionKey Expand(Expression> entityExpand); - IODataOptionKey Expand(Action> entityExpandNested); + IODataOptionKey Expand(Action> entityExpandNested); IODataOptionKey Select(Expression> entitySelect); } diff --git a/src/OData.QueryBuilder/Conventions/Options/IODataOptionList.cs b/src/OData.QueryBuilder/Conventions/Options/IODataOptionList.cs index 6fe78bf3..16496538 100644 --- a/src/OData.QueryBuilder/Conventions/Options/IODataOptionList.cs +++ b/src/OData.QueryBuilder/Conventions/Options/IODataOptionList.cs @@ -16,7 +16,7 @@ public interface IODataOptionList : IODataQuery IODataOptionList Expand(Expression> entityExpand); - IODataOptionList Expand(Action> entityExpandNested); + IODataOptionList Expand(Action> entityExpandNested); IODataOptionList Select(Expression> entitySelect); diff --git a/src/OData.QueryBuilder/Conventions/Options/Nested/IODataOptionNested.cs b/src/OData.QueryBuilder/Conventions/Options/Nested/IODataOptionNested.cs index eef885d5..fd724f6f 100644 --- a/src/OData.QueryBuilder/Conventions/Options/Nested/IODataOptionNested.cs +++ b/src/OData.QueryBuilder/Conventions/Options/Nested/IODataOptionNested.cs @@ -6,7 +6,7 @@ namespace OData.QueryBuilder.Conventions.Options.Nested { public interface IODataOptionNested { - IODataOptionNested Expand(Action> entityExpandNested); + IODataOptionNested Expand(Action> entityExpandNested); IODataOptionNested Expand(Expression> entityNestedExpand); diff --git a/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs b/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs index f13bf37d..20f03f7c 100644 --- a/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs +++ b/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs @@ -8,13 +8,15 @@ namespace OData.QueryBuilder.Conventions.Options.Nested { - public class ODataOptionNested : ODataQueryNested, IODataOptionNested + internal class ODataOptionNested : ODataOptionNestedBase, IODataOptionNested { - internal readonly VisitorExpression _visitorExpression; + private readonly VisitorExpression _visitorExpression; public ODataOptionNested(ODataQueryBuilderOptions odataQueryBuilderOptions) - : base(new StringBuilder(), odataQueryBuilderOptions) => + : base(new StringBuilder(), odataQueryBuilderOptions) + { _visitorExpression = new VisitorExpression(odataQueryBuilderOptions); + } public IODataOptionNested Expand(Expression> entityNestedExpand) { @@ -25,9 +27,9 @@ public IODataOptionNested Expand(Expression> enti return this; } - public IODataOptionNested Expand(Action> actionEntityExpandNested) + public IODataOptionNested Expand(Action> actionEntityExpandNested) { - var builder = new ODataQueryNestedBuilder(_odataQueryBuilderOptions); + var builder = new ODataQueryExpandNestedBuilder(_odataQueryBuilderOptions); actionEntityExpandNested(builder); diff --git a/src/OData.QueryBuilder/ODataQueryNested.cs b/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNestedBase.cs similarity index 69% rename from src/OData.QueryBuilder/ODataQueryNested.cs rename to src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNestedBase.cs index 978fdd16..22b3dce9 100644 --- a/src/OData.QueryBuilder/ODataQueryNested.cs +++ b/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNestedBase.cs @@ -2,14 +2,14 @@ using OData.QueryBuilder.Options; using System.Text; -namespace OData.QueryBuilder +namespace OData.QueryBuilder.Conventions.Options.Nested { - public class ODataQueryNested + internal class ODataOptionNestedBase { protected readonly ODataQueryBuilderOptions _odataQueryBuilderOptions; protected readonly StringBuilder _stringBuilder; - public ODataQueryNested(StringBuilder stringBuilder, ODataQueryBuilderOptions odataQueryBuilderOptions) + public ODataOptionNestedBase(StringBuilder stringBuilder, ODataQueryBuilderOptions odataQueryBuilderOptions) { _stringBuilder = stringBuilder; _odataQueryBuilderOptions = odataQueryBuilderOptions; diff --git a/src/OData.QueryBuilder/Conventions/Options/ODataOption.cs b/src/OData.QueryBuilder/Conventions/Options/ODataOption.cs index f4c56a6c..92e0131f 100644 --- a/src/OData.QueryBuilder/Conventions/Options/ODataOption.cs +++ b/src/OData.QueryBuilder/Conventions/Options/ODataOption.cs @@ -4,14 +4,14 @@ namespace OData.QueryBuilder.Conventions.Options { - public class ODataOption : IODataOption + internal class ODataOption : IODataOption { private readonly ODataQueryBuilderOptions _odataQueryBuilderOptions; private readonly StringBuilder _stringBuilder; - public ODataOption(string resourceUrl, ODataQueryBuilderOptions odataQueryBuilderOptions) + public ODataOption(StringBuilder stringBuilder, ODataQueryBuilderOptions odataQueryBuilderOptions) { - _stringBuilder = new StringBuilder(resourceUrl); + _stringBuilder = stringBuilder; _odataQueryBuilderOptions = odataQueryBuilderOptions; } diff --git a/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs b/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs index 6df477bb..3c0436f5 100644 --- a/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs +++ b/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs @@ -8,9 +8,9 @@ namespace OData.QueryBuilder.Conventions.Options { - public class ODataOptionKey : ODataQuery, IODataOptionKey + internal class ODataOptionKey : ODataQuery, IODataOptionKey { - internal readonly VisitorExpression _visitorExpression; + private readonly VisitorExpression _visitorExpression; public ODataOptionKey(StringBuilder stringBuilder, ODataQueryBuilderOptions odataQueryBuilderOptions) : base(stringBuilder, odataQueryBuilderOptions) => @@ -25,9 +25,9 @@ public IODataOptionKey Expand(Expression> entityE return this; } - public IODataOptionKey Expand(Action> actionEntityExpandNested) + public IODataOptionKey Expand(Action> actionEntityExpandNested) { - var builder = new ODataQueryNestedBuilder(_odataQueryBuilderOptions); + var builder = new ODataQueryExpandNestedBuilder(_odataQueryBuilderOptions); actionEntityExpandNested(builder); diff --git a/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs b/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs index 16f5014f..98e1ec5e 100644 --- a/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs +++ b/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs @@ -10,9 +10,9 @@ namespace OData.QueryBuilder.Conventions.Options { - public class ODataOptionList : ODataQuery, IODataOptionList + internal class ODataOptionList : ODataQuery, IODataOptionList { - internal readonly VisitorExpression _visitorExpression; + private readonly VisitorExpression _visitorExpression; public ODataOptionList(StringBuilder stringBuilder, ODataQueryBuilderOptions odataQueryBuilderOptions) : base(stringBuilder, odataQueryBuilderOptions) => @@ -54,9 +54,10 @@ public IODataOptionList Expand(Expression> entity return this; } - public IODataOptionList Expand(Action> entityExpandNested) + public IODataOptionList Expand(Action> entityExpandNested) { - var builder = new ODataQueryNestedBuilder(_odataQueryBuilderOptions); + var builder = new ODataQueryExpandNestedBuilder(_odataQueryBuilderOptions); + entityExpandNested(builder); _stringBuilder.Append($"{ODataOptionNames.Expand}{QuerySeparators.EqualSignString}{builder.Query}{QuerySeparators.MainString}"); diff --git a/src/OData.QueryBuilder/ODataQuery.cs b/src/OData.QueryBuilder/ODataQuery.cs index 336aadb6..e1891816 100644 --- a/src/OData.QueryBuilder/ODataQuery.cs +++ b/src/OData.QueryBuilder/ODataQuery.cs @@ -6,7 +6,7 @@ namespace OData.QueryBuilder { - public class ODataQuery : IODataQuery + internal class ODataQuery : IODataQuery { protected readonly ODataQueryBuilderOptions _odataQueryBuilderOptions; protected readonly StringBuilder _stringBuilder; diff --git a/test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs b/test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs index 912a9f4c..8da4650f 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryOptionKeyTest.cs @@ -73,8 +73,9 @@ public void ODataQueryBuilderKey_ExpandNested_Select_Success() .Expand(f => { f.For(s => s.ODataKind) - .Expand(ff => ff.For(s => s.ODataCode) - .Select(s => s.IdCode)); + .Expand(ff => ff + .For(s => s.ODataCode) + .Select(s => s.IdCode)); f.For(s => s.ODataKindNew) .Expand(ff => ff.ODataCode) .Select(s => s.IdKind); From 88167506a6ca961df96cefd097ef14d73af211da Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sat, 1 Aug 2020 11:56:34 +0300 Subject: [PATCH 72/76] #ZEXSM#review --- .../Builders/ODataQueryBuilder.cs | 31 +++++------------- .../Conventions/Options/IODataOptionKey.cs | 4 +-- .../Conventions/Options/IODataOptionList.cs | 6 ++-- .../Options/Nested/IODataOptionNested.cs | 4 +-- .../Options/Nested/ODataOptionNested.cs | 8 ++--- .../Conventions/Options/ODataOptionKey.cs | 8 ++--- .../Conventions/Options/ODataOptionList.cs | 8 ++--- .../IODataQueryExpandNestedResource.cs} | 4 +-- .../IODataQueryResource.cs} | 6 ++-- .../ODataQueryExpandNestedResource.cs} | 6 ++-- .../Resources/ODataQueryResource.cs | 32 +++++++++++++++++++ 11 files changed, 67 insertions(+), 50 deletions(-) rename src/OData.QueryBuilder/{Builders/IODataQueryExpandNestedBuilder.cs => Resources/IODataQueryExpandNestedResource.cs} (70%) rename src/OData.QueryBuilder/{Builders/IODataQueryBuilder.cs => Resources/IODataQueryResource.cs} (68%) rename src/OData.QueryBuilder/{Builders/ODataQueryExpandNestedBuilder.cs => Resources/ODataQueryExpandNestedResource.cs} (86%) create mode 100644 src/OData.QueryBuilder/Resources/ODataQueryResource.cs diff --git a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs index 8235e326..6423a20c 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Builders/ODataQueryBuilder.cs @@ -1,40 +1,25 @@ using OData.QueryBuilder.Conventions.Constants; -using OData.QueryBuilder.Conventions.Options; using OData.QueryBuilder.Options; -using OData.QueryBuilder.Visitors; +using OData.QueryBuilder.Resources; using System; -using System.Linq.Expressions; using System.Text; namespace OData.QueryBuilder.Builders { - public class ODataQueryBuilder : IODataQueryBuilder + public class ODataQueryBuilder : ODataQueryResource { - internal readonly VisitorExpression _visitorExpression; - private readonly ODataQueryBuilderOptions _odataQueryBuilderOptions; - private readonly StringBuilder _stringBuilder; - public ODataQueryBuilder(Uri baseUrl, ODataQueryBuilderOptions odataQueryBuilderOptions = default) + : base( + new StringBuilder($"{baseUrl.OriginalString.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"), + odataQueryBuilderOptions ?? new ODataQueryBuilderOptions()) { - _stringBuilder =new StringBuilder($"{baseUrl.OriginalString.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"); - _odataQueryBuilderOptions = odataQueryBuilderOptions ?? new ODataQueryBuilderOptions(); - _visitorExpression = new VisitorExpression(_odataQueryBuilderOptions); } public ODataQueryBuilder(string baseUrl, ODataQueryBuilderOptions odataQueryBuilderOptions = default) + : base( + new StringBuilder($"{baseUrl.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"), + odataQueryBuilderOptions ?? new ODataQueryBuilderOptions()) { - _stringBuilder = new StringBuilder($"{baseUrl.TrimEnd(QuerySeparators.SlashChar)}{QuerySeparators.SlashString}"); - _odataQueryBuilderOptions = odataQueryBuilderOptions ?? new ODataQueryBuilderOptions(); - _visitorExpression = new VisitorExpression(_odataQueryBuilderOptions); - } - - public IODataOption For(Expression> entityResource) - { - var query = _visitorExpression.ToString(entityResource.Body); - - _stringBuilder.Append(query); - - return new ODataOption(_stringBuilder, _odataQueryBuilderOptions); } } } \ No newline at end of file diff --git a/src/OData.QueryBuilder/Conventions/Options/IODataOptionKey.cs b/src/OData.QueryBuilder/Conventions/Options/IODataOptionKey.cs index 747d2be3..0b036d39 100644 --- a/src/OData.QueryBuilder/Conventions/Options/IODataOptionKey.cs +++ b/src/OData.QueryBuilder/Conventions/Options/IODataOptionKey.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.Builders; +using OData.QueryBuilder.Resources; using System; using System.Linq.Expressions; @@ -8,7 +8,7 @@ public interface IODataOptionKey : IODataQuery { IODataOptionKey Expand(Expression> entityExpand); - IODataOptionKey Expand(Action> entityExpandNested); + IODataOptionKey Expand(Action> entityExpandNested); IODataOptionKey Select(Expression> entitySelect); } diff --git a/src/OData.QueryBuilder/Conventions/Options/IODataOptionList.cs b/src/OData.QueryBuilder/Conventions/Options/IODataOptionList.cs index 16496538..6bc7a2bb 100644 --- a/src/OData.QueryBuilder/Conventions/Options/IODataOptionList.cs +++ b/src/OData.QueryBuilder/Conventions/Options/IODataOptionList.cs @@ -1,6 +1,6 @@ -using OData.QueryBuilder.Builders; -using OData.QueryBuilder.Conventions.Functions; +using OData.QueryBuilder.Conventions.Functions; using OData.QueryBuilder.Conventions.Operators; +using OData.QueryBuilder.Resources; using System; using System.Linq.Expressions; @@ -16,7 +16,7 @@ public interface IODataOptionList : IODataQuery IODataOptionList Expand(Expression> entityExpand); - IODataOptionList Expand(Action> entityExpandNested); + IODataOptionList Expand(Action> entityExpandNested); IODataOptionList Select(Expression> entitySelect); diff --git a/src/OData.QueryBuilder/Conventions/Options/Nested/IODataOptionNested.cs b/src/OData.QueryBuilder/Conventions/Options/Nested/IODataOptionNested.cs index fd724f6f..447920d3 100644 --- a/src/OData.QueryBuilder/Conventions/Options/Nested/IODataOptionNested.cs +++ b/src/OData.QueryBuilder/Conventions/Options/Nested/IODataOptionNested.cs @@ -1,4 +1,4 @@ -using OData.QueryBuilder.Builders; +using OData.QueryBuilder.Resources; using System; using System.Linq.Expressions; @@ -6,7 +6,7 @@ namespace OData.QueryBuilder.Conventions.Options.Nested { public interface IODataOptionNested { - IODataOptionNested Expand(Action> entityExpandNested); + IODataOptionNested Expand(Action> entityExpandNested); IODataOptionNested Expand(Expression> entityNestedExpand); diff --git a/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs b/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs index 20f03f7c..ecb718c8 100644 --- a/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs +++ b/src/OData.QueryBuilder/Conventions/Options/Nested/ODataOptionNested.cs @@ -1,6 +1,6 @@ -using OData.QueryBuilder.Builders; -using OData.QueryBuilder.Conventions.Constants; +using OData.QueryBuilder.Conventions.Constants; using OData.QueryBuilder.Options; +using OData.QueryBuilder.Resources; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; @@ -27,9 +27,9 @@ public IODataOptionNested Expand(Expression> enti return this; } - public IODataOptionNested Expand(Action> actionEntityExpandNested) + public IODataOptionNested Expand(Action> actionEntityExpandNested) { - var builder = new ODataQueryExpandNestedBuilder(_odataQueryBuilderOptions); + var builder = new ODataQueryExpandNestedResource(_odataQueryBuilderOptions); actionEntityExpandNested(builder); diff --git a/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs b/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs index 3c0436f5..6ef1d599 100644 --- a/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs +++ b/src/OData.QueryBuilder/Conventions/Options/ODataOptionKey.cs @@ -1,6 +1,6 @@ -using OData.QueryBuilder.Builders; -using OData.QueryBuilder.Conventions.Constants; +using OData.QueryBuilder.Conventions.Constants; using OData.QueryBuilder.Options; +using OData.QueryBuilder.Resources; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; @@ -25,9 +25,9 @@ public IODataOptionKey Expand(Expression> entityE return this; } - public IODataOptionKey Expand(Action> actionEntityExpandNested) + public IODataOptionKey Expand(Action> actionEntityExpandNested) { - var builder = new ODataQueryExpandNestedBuilder(_odataQueryBuilderOptions); + var builder = new ODataQueryExpandNestedResource(_odataQueryBuilderOptions); actionEntityExpandNested(builder); diff --git a/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs b/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs index 98e1ec5e..8f11df83 100644 --- a/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs +++ b/src/OData.QueryBuilder/Conventions/Options/ODataOptionList.cs @@ -1,8 +1,8 @@ -using OData.QueryBuilder.Builders; -using OData.QueryBuilder.Conventions.Constants; +using OData.QueryBuilder.Conventions.Constants; using OData.QueryBuilder.Conventions.Functions; using OData.QueryBuilder.Conventions.Operators; using OData.QueryBuilder.Options; +using OData.QueryBuilder.Resources; using OData.QueryBuilder.Visitors; using System; using System.Linq.Expressions; @@ -54,9 +54,9 @@ public IODataOptionList Expand(Expression> entity return this; } - public IODataOptionList Expand(Action> entityExpandNested) + public IODataOptionList Expand(Action> entityExpandNested) { - var builder = new ODataQueryExpandNestedBuilder(_odataQueryBuilderOptions); + var builder = new ODataQueryExpandNestedResource(_odataQueryBuilderOptions); entityExpandNested(builder); diff --git a/src/OData.QueryBuilder/Builders/IODataQueryExpandNestedBuilder.cs b/src/OData.QueryBuilder/Resources/IODataQueryExpandNestedResource.cs similarity index 70% rename from src/OData.QueryBuilder/Builders/IODataQueryExpandNestedBuilder.cs rename to src/OData.QueryBuilder/Resources/IODataQueryExpandNestedResource.cs index fd06ace5..8656d7bd 100644 --- a/src/OData.QueryBuilder/Builders/IODataQueryExpandNestedBuilder.cs +++ b/src/OData.QueryBuilder/Resources/IODataQueryExpandNestedResource.cs @@ -2,9 +2,9 @@ using System; using System.Linq.Expressions; -namespace OData.QueryBuilder.Builders +namespace OData.QueryBuilder.Resources { - public interface IODataQueryExpandNestedBuilder + public interface IODataQueryExpandNestedResource { IODataOptionNested For(Expression> nestedEntityExpand); } diff --git a/src/OData.QueryBuilder/Builders/IODataQueryBuilder.cs b/src/OData.QueryBuilder/Resources/IODataQueryResource.cs similarity index 68% rename from src/OData.QueryBuilder/Builders/IODataQueryBuilder.cs rename to src/OData.QueryBuilder/Resources/IODataQueryResource.cs index 44617473..daf7fd91 100644 --- a/src/OData.QueryBuilder/Builders/IODataQueryBuilder.cs +++ b/src/OData.QueryBuilder/Resources/IODataQueryResource.cs @@ -2,10 +2,10 @@ using System; using System.Linq.Expressions; -namespace OData.QueryBuilder.Builders +namespace OData.QueryBuilder.Resources { - public interface IODataQueryBuilder + public interface IODataQueryResource { IODataOption For(Expression> entityResource); } -} \ No newline at end of file +} diff --git a/src/OData.QueryBuilder/Builders/ODataQueryExpandNestedBuilder.cs b/src/OData.QueryBuilder/Resources/ODataQueryExpandNestedResource.cs similarity index 86% rename from src/OData.QueryBuilder/Builders/ODataQueryExpandNestedBuilder.cs rename to src/OData.QueryBuilder/Resources/ODataQueryExpandNestedResource.cs index bec5e32c..a1cb5c8f 100644 --- a/src/OData.QueryBuilder/Builders/ODataQueryExpandNestedBuilder.cs +++ b/src/OData.QueryBuilder/Resources/ODataQueryExpandNestedResource.cs @@ -5,9 +5,9 @@ using System.Linq.Expressions; using System.Text; -namespace OData.QueryBuilder.Builders +namespace OData.QueryBuilder.Resources { - internal class ODataQueryExpandNestedBuilder : IODataQueryExpandNestedBuilder + internal class ODataQueryExpandNestedResource : IODataQueryExpandNestedResource { private readonly ODataQueryBuilderOptions _odataQueryBuilderOptions; private readonly StringBuilder _stringBuilder; @@ -16,7 +16,7 @@ internal class ODataQueryExpandNestedBuilder : IODataQueryExpandNestedB public string Query => $"{_stringBuilder}({_odataOptionNestedBase.Query})"; - public ODataQueryExpandNestedBuilder(ODataQueryBuilderOptions odataQueryBuilderOptions) + public ODataQueryExpandNestedResource(ODataQueryBuilderOptions odataQueryBuilderOptions) { _stringBuilder = new StringBuilder(); _odataQueryBuilderOptions = odataQueryBuilderOptions; diff --git a/src/OData.QueryBuilder/Resources/ODataQueryResource.cs b/src/OData.QueryBuilder/Resources/ODataQueryResource.cs new file mode 100644 index 00000000..dfcef03a --- /dev/null +++ b/src/OData.QueryBuilder/Resources/ODataQueryResource.cs @@ -0,0 +1,32 @@ +using OData.QueryBuilder.Conventions.Options; +using OData.QueryBuilder.Options; +using OData.QueryBuilder.Visitors; +using System; +using System.Linq.Expressions; +using System.Text; + +namespace OData.QueryBuilder.Resources +{ + public class ODataQueryResource : IODataQueryResource + { + private readonly VisitorExpression _visitorExpression; + private readonly ODataQueryBuilderOptions _odataQueryBuilderOptions; + private readonly StringBuilder _stringBuilder; + + public ODataQueryResource(StringBuilder stringBuilder, ODataQueryBuilderOptions odataQueryBuilderOptions) + { + _visitorExpression = new VisitorExpression(odataQueryBuilderOptions); + _odataQueryBuilderOptions = odataQueryBuilderOptions; + _stringBuilder = stringBuilder; + } + + public IODataOption For(Expression> entityResource) + { + var query = _visitorExpression.ToString(entityResource.Body); + + _stringBuilder.Append(query); + + return new ODataOption(_stringBuilder, _odataQueryBuilderOptions); + } + } +} From 0467b111111044b0f6605ca3e174bde07609a85e Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sat, 1 Aug 2020 12:34:59 +0300 Subject: [PATCH 73/76] #ZEXSM#obsolete substringof --- .../Functions/IODataStringAndCollectionFunction.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/OData.QueryBuilder/Conventions/Functions/IODataStringAndCollectionFunction.cs b/src/OData.QueryBuilder/Conventions/Functions/IODataStringAndCollectionFunction.cs index d785b7a5..66612978 100644 --- a/src/OData.QueryBuilder/Conventions/Functions/IODataStringAndCollectionFunction.cs +++ b/src/OData.QueryBuilder/Conventions/Functions/IODataStringAndCollectionFunction.cs @@ -1,10 +1,16 @@ -namespace OData.QueryBuilder.Conventions.Functions +using System; + +namespace OData.QueryBuilder.Conventions.Functions { /// /// http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_StringandCollectionFunctions /// public interface IODataStringAndCollectionFunction { + /// + /// + /// + [Obsolete("Use Contains OData Version 4.0 Protocol function if possible")] bool SubstringOf(string value, string columnName); /// From 237a4fad9bc14f54dde796aebf8a0030485b76ab Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sat, 1 Aug 2020 13:16:04 +0300 Subject: [PATCH 74/76] test travis --- .travis.yml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index acf8f3d5..dd624c5a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,18 @@ after_success: - cd src/OData.QueryBuilder && dotnet minicover instrument --workdir ../../coverage --parentdir ../ --assemblies test/**/bin/$CONFIGURATION/**/*.dll --sources src/**/*.cs && dotnet minicover reset --workdir ../../coverage && cd ../../ - dotnet test --no-build ./test/OData.QueryBuilder.Test - cd src/OData.QueryBuilder && dotnet minicover uninstrument --workdir ../../coverage && dotnet minicover report --workdir ../../coverage && dotnet minicover coverallsreport --workdir ../../coverage --root-path ../../ --output "coveralls.json" --service-name "travis-ci" --service-job-id $TRAVIS_JOB_ID && cd ../../ + - PR_TITLE="Merge-pull-request-#23-from-ZEXSM/release-rc/review-library" + - LAST_TAG="2.0.0-rc.3" + - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) + - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) + - CURRENT_PATCH=$(echo $(echo $LAST_TAG | cut -d. -f 3) | cut -d- -f 1) + - RC=$(echo $(echo $LAST_TAG | cut -d. -f 3) | cut -d- -f 2) + - MAJOR=$(([ "$RC" == "rc" ] && echo $CURRENT_MAJOR) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1))) || echo $CURRENT_MAJOR) + - MINOR=$(([ "$RC" == "rc" ] && echo $CURRENT_MINOR) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) + - PATCH=$(([ "$RC" == "rc" ] && echo $CURRENT_PATCH) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) + - NEW_TAG=$(echo $MAJOR.$MINOR.$PATCH) + - echo $NEW_TAG + - echo RC before_deploy: - git checkout origin/master && git fetch && git remote set-url origin https://${GITHUB_OAUTH_TOKEN}@github.com/ZEXSM/OData.QueryBuilder.git - PR_TITLE=$(git log -1 --pretty='%f') @@ -24,9 +36,10 @@ before_deploy: - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - CURRENT_PATCH=$(echo $(echo $LAST_TAG | cut -d. -f 3) | cut -d- -f 1) - - MAJOR=$([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1)) || echo $CURRENT_MAJOR) - - MINOR=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - - PATCH=$(([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) + - RC=$(echo $(echo $LAST_TAG | cut -d. -f 3) | cut -d- -f 2) + - MAJOR=$(([ "$RC" == "rc" ] && echo $CURRENT_MAJOR) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1))) || echo $CURRENT_MAJOR) + - MINOR=$(([ "$RC" == "rc" ] && echo $CURRENT_MINOR) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) + - PATCH=$(([ "$RC" == "rc" ] && echo $CURRENT_PATCH) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - NEW_TAG=$(echo $MAJOR.$MINOR.$PATCH) - PACKAGE_VERSION=${NEW_TAG:-$DEFAULT_PACKAGE_VERSION} - git tag v$PACKAGE_VERSION && git push origin v$PACKAGE_VERSION From d8447cd8aee4832b2576fe7658b89041253f2843 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sat, 1 Aug 2020 13:18:21 +0300 Subject: [PATCH 75/76] test travis --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index dd624c5a..4d6fdae1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,8 +17,9 @@ after_success: - cd src/OData.QueryBuilder && dotnet minicover instrument --workdir ../../coverage --parentdir ../ --assemblies test/**/bin/$CONFIGURATION/**/*.dll --sources src/**/*.cs && dotnet minicover reset --workdir ../../coverage && cd ../../ - dotnet test --no-build ./test/OData.QueryBuilder.Test - cd src/OData.QueryBuilder && dotnet minicover uninstrument --workdir ../../coverage && dotnet minicover report --workdir ../../coverage && dotnet minicover coverallsreport --workdir ../../coverage --root-path ../../ --output "coveralls.json" --service-name "travis-ci" --service-job-id $TRAVIS_JOB_ID && cd ../../ + - git checkout origin/master && git fetch && git remote set-url origin https://${GITHUB_OAUTH_TOKEN}@github.com/ZEXSM/OData.QueryBuilder.git - PR_TITLE="Merge-pull-request-#23-from-ZEXSM/release-rc/review-library" - - LAST_TAG="2.0.0-rc.3" + - LAST_TAG=$(echo $(git describe --tags $(git rev-list --tags --max-count=1)) | cut -d'v' -f 2) - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - CURRENT_PATCH=$(echo $(echo $LAST_TAG | cut -d. -f 3) | cut -d- -f 1) @@ -28,7 +29,7 @@ after_success: - PATCH=$(([ "$RC" == "rc" ] && echo $CURRENT_PATCH) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - NEW_TAG=$(echo $MAJOR.$MINOR.$PATCH) - echo $NEW_TAG - - echo RC + - echo $RC before_deploy: - git checkout origin/master && git fetch && git remote set-url origin https://${GITHUB_OAUTH_TOKEN}@github.com/ZEXSM/OData.QueryBuilder.git - PR_TITLE=$(git log -1 --pretty='%f') From 1e77ed6330fa98180557f86f45571246d875ff55 Mon Sep 17 00:00:00 2001 From: ZEXSM Date: Sat, 1 Aug 2020 13:21:18 +0300 Subject: [PATCH 76/76] travis --- .travis.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4d6fdae1..bd84679e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,19 +17,6 @@ after_success: - cd src/OData.QueryBuilder && dotnet minicover instrument --workdir ../../coverage --parentdir ../ --assemblies test/**/bin/$CONFIGURATION/**/*.dll --sources src/**/*.cs && dotnet minicover reset --workdir ../../coverage && cd ../../ - dotnet test --no-build ./test/OData.QueryBuilder.Test - cd src/OData.QueryBuilder && dotnet minicover uninstrument --workdir ../../coverage && dotnet minicover report --workdir ../../coverage && dotnet minicover coverallsreport --workdir ../../coverage --root-path ../../ --output "coveralls.json" --service-name "travis-ci" --service-job-id $TRAVIS_JOB_ID && cd ../../ - - git checkout origin/master && git fetch && git remote set-url origin https://${GITHUB_OAUTH_TOKEN}@github.com/ZEXSM/OData.QueryBuilder.git - - PR_TITLE="Merge-pull-request-#23-from-ZEXSM/release-rc/review-library" - - LAST_TAG=$(echo $(git describe --tags $(git rev-list --tags --max-count=1)) | cut -d'v' -f 2) - - CURRENT_MAJOR=$(echo $LAST_TAG | cut -d. -f 1) - - CURRENT_MINOR=$(echo $LAST_TAG | cut -d. -f 2) - - CURRENT_PATCH=$(echo $(echo $LAST_TAG | cut -d. -f 3) | cut -d- -f 1) - - RC=$(echo $(echo $LAST_TAG | cut -d. -f 3) | cut -d- -f 2) - - MAJOR=$(([ "$RC" == "rc" ] && echo $CURRENT_MAJOR) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo $(($CURRENT_MAJOR+1))) || echo $CURRENT_MAJOR) - - MINOR=$(([ "$RC" == "rc" ] && echo $CURRENT_MINOR) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo $(($CURRENT_MINOR+1))) || echo $CURRENT_MINOR) - - PATCH=$(([ "$RC" == "rc" ] && echo $CURRENT_PATCH) || ([ "$(echo $PR_TITLE | grep -oP 'release')" == "release" ] && echo 0) || ([ "$(echo $PR_TITLE | grep -oP 'feature')" == "feature" ] && echo 0) || echo $(($CURRENT_PATCH+1))) - - NEW_TAG=$(echo $MAJOR.$MINOR.$PATCH) - - echo $NEW_TAG - - echo $RC before_deploy: - git checkout origin/master && git fetch && git remote set-url origin https://${GITHUB_OAUTH_TOKEN}@github.com/ZEXSM/OData.QueryBuilder.git - PR_TITLE=$(git log -1 --pretty='%f')