mirror of https://github.com/Squidex/squidex.git
54 changed files with 640 additions and 590 deletions
@ -0,0 +1,87 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
namespace Squidex.Infrastructure.Queries |
||||
|
{ |
||||
|
public static class ClrFilter |
||||
|
{ |
||||
|
public static LogicalFilter<ClrValue> And(params FilterNode<ClrValue>[] filters) |
||||
|
{ |
||||
|
return new LogicalFilter<ClrValue>(LogicalFilterType.And, filters); |
||||
|
} |
||||
|
|
||||
|
public static LogicalFilter<ClrValue> Or(params FilterNode<ClrValue>[] filters) |
||||
|
{ |
||||
|
return new LogicalFilter<ClrValue>(LogicalFilterType.Or, filters); |
||||
|
} |
||||
|
|
||||
|
public static NegateFilter<ClrValue> Not(FilterNode<ClrValue> filter) |
||||
|
{ |
||||
|
return new NegateFilter<ClrValue>(filter); |
||||
|
} |
||||
|
|
||||
|
public static CompareFilter<ClrValue> Eq(PropertyPath path, ClrValue value) |
||||
|
{ |
||||
|
return Binary(path, CompareOperator.Equals, value); |
||||
|
} |
||||
|
|
||||
|
public static CompareFilter<ClrValue> Ne(PropertyPath path, ClrValue value) |
||||
|
{ |
||||
|
return Binary(path, CompareOperator.NotEquals, value); |
||||
|
} |
||||
|
|
||||
|
public static CompareFilter<ClrValue> Lt(PropertyPath path, ClrValue value) |
||||
|
{ |
||||
|
return Binary(path, CompareOperator.LessThan, value); |
||||
|
} |
||||
|
|
||||
|
public static CompareFilter<ClrValue> Le(PropertyPath path, ClrValue value) |
||||
|
{ |
||||
|
return Binary(path, CompareOperator.LessThanOrEqual, value); |
||||
|
} |
||||
|
|
||||
|
public static CompareFilter<ClrValue> Gt(PropertyPath path, ClrValue value) |
||||
|
{ |
||||
|
return Binary(path, CompareOperator.GreaterThan, value); |
||||
|
} |
||||
|
|
||||
|
public static CompareFilter<ClrValue> Ge(PropertyPath path, ClrValue value) |
||||
|
{ |
||||
|
return Binary(path, CompareOperator.GreaterThanOrEqual, value); |
||||
|
} |
||||
|
|
||||
|
public static CompareFilter<ClrValue> Contains(PropertyPath path, ClrValue value) |
||||
|
{ |
||||
|
return Binary(path, CompareOperator.Contains, value); |
||||
|
} |
||||
|
|
||||
|
public static CompareFilter<ClrValue> EndsWith(PropertyPath path, ClrValue value) |
||||
|
{ |
||||
|
return Binary(path, CompareOperator.EndsWith, value); |
||||
|
} |
||||
|
|
||||
|
public static CompareFilter<ClrValue> StartsWith(PropertyPath path, ClrValue value) |
||||
|
{ |
||||
|
return Binary(path, CompareOperator.StartsWith, value); |
||||
|
} |
||||
|
|
||||
|
public static CompareFilter<ClrValue> Empty(PropertyPath path) |
||||
|
{ |
||||
|
return Binary(path, CompareOperator.Empty, null); |
||||
|
} |
||||
|
|
||||
|
public static CompareFilter<ClrValue> In(PropertyPath path, ClrValue value) |
||||
|
{ |
||||
|
return Binary(path, CompareOperator.In, value); |
||||
|
} |
||||
|
|
||||
|
private static CompareFilter<ClrValue> Binary(PropertyPath path, CompareOperator @operator, ClrValue value) |
||||
|
{ |
||||
|
return new CompareFilter<ClrValue>(path, @operator, value ?? ClrValue.Null); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
namespace Squidex.Infrastructure.Queries |
||||
|
{ |
||||
|
public sealed class ClrQuery : Query<ClrValue> |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,140 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Globalization; |
||||
|
using System.Linq; |
||||
|
using NodaTime; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Queries |
||||
|
{ |
||||
|
public sealed class ClrValue |
||||
|
{ |
||||
|
public static readonly ClrValue Null = new ClrValue(null, ClrValueType.Null, false); |
||||
|
|
||||
|
public object Value { get; } |
||||
|
|
||||
|
public ClrValueType ValueType { get; } |
||||
|
|
||||
|
public bool IsList { get; } |
||||
|
|
||||
|
private ClrValue(object value, ClrValueType valueType, bool isList) |
||||
|
{ |
||||
|
Value = value; |
||||
|
ValueType = valueType; |
||||
|
|
||||
|
IsList = isList; |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(Instant value) |
||||
|
{ |
||||
|
return new ClrValue(value, ClrValueType.Instant, false); |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(Guid value) |
||||
|
{ |
||||
|
return new ClrValue(value, ClrValueType.Guid, false); |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(bool value) |
||||
|
{ |
||||
|
return new ClrValue(value, ClrValueType.Boolean, false); |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(float value) |
||||
|
{ |
||||
|
return new ClrValue(value, ClrValueType.Single, false); |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(double value) |
||||
|
{ |
||||
|
return new ClrValue(value, ClrValueType.Double, false); |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(int value) |
||||
|
{ |
||||
|
return new ClrValue(value, ClrValueType.Int32, false); |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(long value) |
||||
|
{ |
||||
|
return new ClrValue(value, ClrValueType.Int64, false); |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(string value) |
||||
|
{ |
||||
|
return value != null ? new ClrValue(value, ClrValueType.String, false) : Null; |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(List<Instant> value) |
||||
|
{ |
||||
|
return value != null ? new ClrValue(value, ClrValueType.Instant, true) : Null; |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(List<Guid> value) |
||||
|
{ |
||||
|
return value != null ? new ClrValue(value, ClrValueType.Guid, true) : Null; |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(List<bool> value) |
||||
|
{ |
||||
|
return value != null ? new ClrValue(value, ClrValueType.Boolean, true) : Null; |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(List<float> value) |
||||
|
{ |
||||
|
return value != null ? new ClrValue(value, ClrValueType.Single, true) : Null; |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(List<double> value) |
||||
|
{ |
||||
|
return value != null ? new ClrValue(value, ClrValueType.Double, true) : Null; |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(List<int> value) |
||||
|
{ |
||||
|
return value != null ? new ClrValue(value, ClrValueType.Int32, true) : Null; |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(List<long> value) |
||||
|
{ |
||||
|
return value != null ? new ClrValue(value, ClrValueType.Int64, true) : Null; |
||||
|
} |
||||
|
|
||||
|
public static implicit operator ClrValue(List<string> value) |
||||
|
{ |
||||
|
return value != null ? new ClrValue(value, ClrValueType.String, true) : Null; |
||||
|
} |
||||
|
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
if (Value is IList list) |
||||
|
{ |
||||
|
return $"[{string.Join(", ", list.OfType<object>().Select(ToString).ToArray())}]"; |
||||
|
} |
||||
|
|
||||
|
return ToString(Value); |
||||
|
} |
||||
|
|
||||
|
private static string ToString(object value) |
||||
|
{ |
||||
|
if (value == null) |
||||
|
{ |
||||
|
return "null"; |
||||
|
} |
||||
|
|
||||
|
if (value is string s) |
||||
|
{ |
||||
|
return $"'{s.Replace("'", "\\'")}'"; |
||||
|
} |
||||
|
|
||||
|
return string.Format(CultureInfo.InvariantCulture, "{0}", value); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,67 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
namespace Squidex.Infrastructure.Queries |
||||
|
{ |
||||
|
public sealed class CompareFilter<TValue> : FilterNode<TValue> |
||||
|
{ |
||||
|
public PropertyPath Path { get; } |
||||
|
|
||||
|
public CompareOperator Operator { get; } |
||||
|
|
||||
|
public TValue Value { get; } |
||||
|
|
||||
|
public CompareFilter(PropertyPath path, CompareOperator @operator, TValue value) |
||||
|
{ |
||||
|
Guard.NotNull(path, nameof(path)); |
||||
|
Guard.NotNull(value, nameof(value)); |
||||
|
Guard.Enum(@operator, nameof(@operator)); |
||||
|
|
||||
|
Path = path; |
||||
|
|
||||
|
Operator = @operator; |
||||
|
|
||||
|
Value = value; |
||||
|
} |
||||
|
|
||||
|
public override T Accept<T>(FilterNodeVisitor<T, TValue> visitor) |
||||
|
{ |
||||
|
return visitor.Visit(this); |
||||
|
} |
||||
|
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
switch (Operator) |
||||
|
{ |
||||
|
case CompareOperator.Contains: |
||||
|
return $"contains({Path}, {Value})"; |
||||
|
case CompareOperator.Empty: |
||||
|
return $"empty({Path})"; |
||||
|
case CompareOperator.EndsWith: |
||||
|
return $"endsWith({Path}, {Value})"; |
||||
|
case CompareOperator.StartsWith: |
||||
|
return $"startsWith({Path}, {Value})"; |
||||
|
case CompareOperator.Equals: |
||||
|
return $"{Path} == {Value}"; |
||||
|
case CompareOperator.NotEquals: |
||||
|
return $"{Path} != {Value}"; |
||||
|
case CompareOperator.GreaterThan: |
||||
|
return $"{Path} > {Value}"; |
||||
|
case CompareOperator.GreaterThanOrEqual: |
||||
|
return $"{Path} >= {Value}"; |
||||
|
case CompareOperator.LessThan: |
||||
|
return $"{Path} < {Value}"; |
||||
|
case CompareOperator.LessThanOrEqual: |
||||
|
return $"{Path} <= {Value}"; |
||||
|
case CompareOperator.In: |
||||
|
return $"{Path} in {Value}"; |
||||
|
default: |
||||
|
return string.Empty; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,85 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Linq; |
|
||||
using NodaTime; |
|
||||
|
|
||||
namespace Squidex.Infrastructure.Queries |
|
||||
{ |
|
||||
public static class FilterBuilder |
|
||||
{ |
|
||||
public static FilterJunction And(params FilterNode[] operands) |
|
||||
{ |
|
||||
return new FilterJunction(FilterJunctionType.And, operands); |
|
||||
} |
|
||||
|
|
||||
public static FilterJunction Or(params FilterNode[] operands) |
|
||||
{ |
|
||||
return new FilterJunction(FilterJunctionType.Or, operands); |
|
||||
} |
|
||||
|
|
||||
public static FilterComparison Eq(string path, string value) |
|
||||
{ |
|
||||
return Binary(path, FilterOperator.Equals, value); |
|
||||
} |
|
||||
|
|
||||
public static FilterComparison Eq(string path, bool value) |
|
||||
{ |
|
||||
return Binary(path, FilterOperator.Equals, value); |
|
||||
} |
|
||||
|
|
||||
public static FilterComparison Eq(string path, long value) |
|
||||
{ |
|
||||
return Binary(path, FilterOperator.Equals, value); |
|
||||
} |
|
||||
|
|
||||
public static FilterComparison Eq(string path, int value) |
|
||||
{ |
|
||||
return Binary(path, FilterOperator.Equals, value); |
|
||||
} |
|
||||
|
|
||||
public static FilterComparison Eq(string path, Instant value) |
|
||||
{ |
|
||||
return Binary(path, FilterOperator.Equals, value); |
|
||||
} |
|
||||
|
|
||||
public static FilterComparison Empty(string path) |
|
||||
{ |
|
||||
return new FilterComparison(path.Split('.', '/'), FilterOperator.Empty, FilterValue.Null); |
|
||||
} |
|
||||
|
|
||||
public static FilterComparison In(string path, params long[] value) |
|
||||
{ |
|
||||
return new FilterComparison(path.Split('.', '/'), FilterOperator.In, new FilterValue(value.ToList())); |
|
||||
} |
|
||||
|
|
||||
private static FilterComparison Binary(string path, FilterOperator @operator, string value) |
|
||||
{ |
|
||||
return new FilterComparison(path.Split('.', '/'), @operator, new FilterValue(value)); |
|
||||
} |
|
||||
|
|
||||
private static FilterComparison Binary(string path, FilterOperator @operator, bool value) |
|
||||
{ |
|
||||
return new FilterComparison(path.Split('.', '/'), @operator, new FilterValue(value)); |
|
||||
} |
|
||||
|
|
||||
private static FilterComparison Binary(string path, FilterOperator @operator, long value) |
|
||||
{ |
|
||||
return new FilterComparison(path.Split('.', '/'), @operator, new FilterValue(value)); |
|
||||
} |
|
||||
|
|
||||
private static FilterComparison Binary(string path, FilterOperator @operator, int value) |
|
||||
{ |
|
||||
return new FilterComparison(path.Split('.', '/'), @operator, new FilterValue(value)); |
|
||||
} |
|
||||
|
|
||||
private static FilterComparison Binary(string path, FilterOperator @operator, Instant value) |
|
||||
{ |
|
||||
return new FilterComparison(path.Split('.', '/'), @operator, new FilterValue(value)); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,70 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Collections.Generic; |
|
||||
|
|
||||
namespace Squidex.Infrastructure.Queries |
|
||||
{ |
|
||||
public sealed class FilterComparison : FilterNode |
|
||||
{ |
|
||||
public IReadOnlyList<string> Lhs { get; } |
|
||||
|
|
||||
public FilterOperator Operator { get; } |
|
||||
|
|
||||
public FilterValue Rhs { get; } |
|
||||
|
|
||||
public FilterComparison(IReadOnlyList<string> lhs, FilterOperator @operator, FilterValue rhs) |
|
||||
{ |
|
||||
Guard.NotNull(lhs, nameof(lhs)); |
|
||||
Guard.NotEmpty(lhs, nameof(lhs)); |
|
||||
Guard.Enum(@operator, nameof(@operator)); |
|
||||
|
|
||||
Lhs = lhs; |
|
||||
Rhs = rhs; |
|
||||
|
|
||||
Operator = @operator; |
|
||||
} |
|
||||
|
|
||||
public override T Accept<T>(FilterNodeVisitor<T> visitor) |
|
||||
{ |
|
||||
return visitor.Visit(this); |
|
||||
} |
|
||||
|
|
||||
public override string ToString() |
|
||||
{ |
|
||||
var path = string.Join(".", Lhs); |
|
||||
|
|
||||
switch (Operator) |
|
||||
{ |
|
||||
case FilterOperator.Contains: |
|
||||
return $"contains({path}, {Rhs})"; |
|
||||
case FilterOperator.Empty: |
|
||||
return $"empty({path})"; |
|
||||
case FilterOperator.EndsWith: |
|
||||
return $"endsWith({path}, {Rhs})"; |
|
||||
case FilterOperator.StartsWith: |
|
||||
return $"startsWith({path}, {Rhs})"; |
|
||||
case FilterOperator.Equals: |
|
||||
return $"{path} == {Rhs}"; |
|
||||
case FilterOperator.NotEquals: |
|
||||
return $"{path} != {Rhs}"; |
|
||||
case FilterOperator.GreaterThan: |
|
||||
return $"{path} > {Rhs}"; |
|
||||
case FilterOperator.GreaterThanOrEqual: |
|
||||
return $"{path} >= {Rhs}"; |
|
||||
case FilterOperator.LessThan: |
|
||||
return $"{path} < {Rhs}"; |
|
||||
case FilterOperator.LessThanOrEqual: |
|
||||
return $"{path} <= {Rhs}"; |
|
||||
case FilterOperator.In: |
|
||||
return $"{path} in {Rhs}"; |
|
||||
default: |
|
||||
return string.Empty; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,45 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
|
|
||||
namespace Squidex.Infrastructure.Queries |
|
||||
{ |
|
||||
public sealed class FilterJunction : FilterNode |
|
||||
{ |
|
||||
public IReadOnlyList<FilterNode> Operands { get; } |
|
||||
|
|
||||
public FilterJunctionType JunctionType { get; } |
|
||||
|
|
||||
public FilterJunction(FilterJunctionType junctionType, IReadOnlyList<FilterNode> operands) |
|
||||
{ |
|
||||
Guard.NotNull(operands, nameof(operands)); |
|
||||
Guard.GreaterEquals(operands.Count, 2, nameof(operands.Count)); |
|
||||
Guard.Enum(junctionType, nameof(junctionType)); |
|
||||
|
|
||||
Operands = operands; |
|
||||
|
|
||||
JunctionType = junctionType; |
|
||||
} |
|
||||
|
|
||||
public FilterJunction(FilterJunctionType junctionType, params FilterNode[] operands) |
|
||||
: this(junctionType, operands?.ToList()) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public override T Accept<T>(FilterNodeVisitor<T> visitor) |
|
||||
{ |
|
||||
return visitor.Visit(this); |
|
||||
} |
|
||||
|
|
||||
public override string ToString() |
|
||||
{ |
|
||||
return $"({string.Join(JunctionType == FilterJunctionType.And ? " && " : " || ", Operands)})"; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,149 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using System.Collections; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Globalization; |
|
||||
using System.Linq; |
|
||||
using NodaTime; |
|
||||
|
|
||||
namespace Squidex.Infrastructure.Queries |
|
||||
{ |
|
||||
public sealed class FilterValue |
|
||||
{ |
|
||||
public static readonly FilterValue Null = new FilterValue(null, FilterValueType.Null, false); |
|
||||
|
|
||||
public object Value { get; } |
|
||||
|
|
||||
public FilterValueType ValueType { get; } |
|
||||
|
|
||||
public bool IsList { get; } |
|
||||
|
|
||||
public FilterValue(Guid value) |
|
||||
: this(value, FilterValueType.Guid, false) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public FilterValue(Instant value) |
|
||||
: this(value, FilterValueType.Instant, false) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public FilterValue(bool value) |
|
||||
: this(value, FilterValueType.Boolean, false) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public FilterValue(float value) |
|
||||
: this(value, FilterValueType.Single, false) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public FilterValue(double value) |
|
||||
: this(value, FilterValueType.Double, false) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public FilterValue(int value) |
|
||||
: this(value, FilterValueType.Int32, false) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public FilterValue(long value) |
|
||||
: this(value, FilterValueType.Int64, false) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public FilterValue(string value) |
|
||||
: this(value, FilterValueType.String, false) |
|
||||
{ |
|
||||
Guard.NotNull(value, nameof(value)); |
|
||||
} |
|
||||
|
|
||||
public FilterValue(List<Guid> value) |
|
||||
: this(value, FilterValueType.Guid, true) |
|
||||
{ |
|
||||
Guard.NotNull(value, nameof(value)); |
|
||||
} |
|
||||
|
|
||||
public FilterValue(List<Instant> value) |
|
||||
: this(value, FilterValueType.Instant, true) |
|
||||
{ |
|
||||
Guard.NotNull(value, nameof(value)); |
|
||||
} |
|
||||
|
|
||||
public FilterValue(List<bool> value) |
|
||||
: this(value, FilterValueType.Boolean, true) |
|
||||
{ |
|
||||
Guard.NotNull(value, nameof(value)); |
|
||||
} |
|
||||
|
|
||||
public FilterValue(List<float> value) |
|
||||
: this(value, FilterValueType.Single, true) |
|
||||
{ |
|
||||
Guard.NotNull(value, nameof(value)); |
|
||||
} |
|
||||
|
|
||||
public FilterValue(List<double> value) |
|
||||
: this(value, FilterValueType.Double, true) |
|
||||
{ |
|
||||
Guard.NotNull(value, nameof(value)); |
|
||||
} |
|
||||
|
|
||||
public FilterValue(List<int> value) |
|
||||
: this(value, FilterValueType.Int32, true) |
|
||||
{ |
|
||||
Guard.NotNull(value, nameof(value)); |
|
||||
} |
|
||||
|
|
||||
public FilterValue(List<long> value) |
|
||||
: this(value, FilterValueType.Int64, true) |
|
||||
{ |
|
||||
Guard.NotNull(value, nameof(value)); |
|
||||
} |
|
||||
|
|
||||
public FilterValue(List<string> value) |
|
||||
: this(value, FilterValueType.String, true) |
|
||||
{ |
|
||||
Guard.NotNull(value, nameof(value)); |
|
||||
} |
|
||||
|
|
||||
private FilterValue(object value, FilterValueType valueType, bool isList) |
|
||||
{ |
|
||||
Value = value; |
|
||||
ValueType = valueType; |
|
||||
|
|
||||
IsList = isList; |
|
||||
} |
|
||||
|
|
||||
public override string ToString() |
|
||||
{ |
|
||||
if (Value is IList list) |
|
||||
{ |
|
||||
return $"[{string.Join(", ", list.OfType<object>().Select(ToString).ToArray())}]"; |
|
||||
} |
|
||||
|
|
||||
return ToString(Value); |
|
||||
} |
|
||||
|
|
||||
private static string ToString(object value) |
|
||||
{ |
|
||||
if (value == null) |
|
||||
{ |
|
||||
return "null"; |
|
||||
} |
|
||||
|
|
||||
if (value is string s) |
|
||||
{ |
|
||||
return $"'{s.Replace("'", "\\'")}'"; |
|
||||
} |
|
||||
|
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0}", value); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,39 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Queries |
||||
|
{ |
||||
|
public sealed class LogicalFilter<TValue> : FilterNode<TValue> |
||||
|
{ |
||||
|
public IReadOnlyList<FilterNode<TValue>> Filters { get; } |
||||
|
|
||||
|
public LogicalFilterType Type { get; } |
||||
|
|
||||
|
public LogicalFilter(LogicalFilterType type, IReadOnlyList<FilterNode<TValue>> filters) |
||||
|
{ |
||||
|
Guard.NotNull(filters, nameof(filters)); |
||||
|
Guard.GreaterEquals(filters.Count, 2, nameof(filters.Count)); |
||||
|
Guard.Enum(type, nameof(type)); |
||||
|
|
||||
|
Filters = filters; |
||||
|
|
||||
|
Type = type; |
||||
|
} |
||||
|
|
||||
|
public override T Accept<T>(FilterNodeVisitor<T, TValue> visitor) |
||||
|
{ |
||||
|
return visitor.Visit(this); |
||||
|
} |
||||
|
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
return $"({string.Join(Type == LogicalFilterType.And ? " && " : " || ", Filters)})"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Collections.Immutable; |
||||
|
using System.Collections.ObjectModel; |
||||
|
using System.Linq; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Queries |
||||
|
{ |
||||
|
public sealed class PropertyPath : ReadOnlyCollection<string> |
||||
|
{ |
||||
|
public PropertyPath(IList<string> items) |
||||
|
: base(items) |
||||
|
{ |
||||
|
if (items.Count == 0) |
||||
|
{ |
||||
|
throw new ArgumentException("Path cannot be empty.", nameof(items)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static implicit operator PropertyPath(string path) |
||||
|
{ |
||||
|
return new PropertyPath(path?.Split('.', '/')?.ToList()); |
||||
|
} |
||||
|
|
||||
|
public static implicit operator PropertyPath(string[] path) |
||||
|
{ |
||||
|
return new PropertyPath(path?.ToList()); |
||||
|
} |
||||
|
|
||||
|
public static implicit operator PropertyPath(List<string> path) |
||||
|
{ |
||||
|
return new PropertyPath(path); |
||||
|
} |
||||
|
|
||||
|
public static implicit operator PropertyPath(ImmutableList<string> path) |
||||
|
{ |
||||
|
return new PropertyPath(path); |
||||
|
} |
||||
|
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
return string.Join(".", this); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue