Browse Source

Fix date filter.

pull/421/head
Sebastian 6 years ago
parent
commit
0c620b7c23
  1. 83
      src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/Adapt.cs
  2. 14
      src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/AdaptionVisitor.cs
  3. 71
      src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/FilterFactory.cs
  4. 22
      src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/FilterVisitor.cs
  5. 4
      tests/Squidex.Domain.Apps.Entities.Tests/Contents/MongoDb/MongoDbQueryTests.cs

83
src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/Adapt.cs

@ -0,0 +1,83 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using MongoDB.Bson.Serialization.Attributes;
using Squidex.Domain.Apps.Core.GenerateEdmSchema;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Queries;
namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Visitors
{
public static class Adapt
{
private static readonly Dictionary<string, string> PropertyMap =
typeof(MongoContentEntity).GetProperties()
.ToDictionary(x => x.Name, x => x.GetCustomAttribute<BsonElementAttribute>()?.ElementName ?? x.Name, StringComparer.OrdinalIgnoreCase);
public static Func<PropertyPath, PropertyPath> Path(Schema schema, bool inDraft)
{
return propertyNames =>
{
var result = new List<string>(propertyNames);
if (result.Count > 1)
{
var edmName = result[1].UnescapeEdmField();
if (!schema.FieldsByName.TryGetValue(edmName, out var field))
{
throw new NotSupportedException();
}
result[1] = field.Id.ToString();
if (field is IArrayField arrayField && result.Count > 3)
{
var nestedEdmName = result[3].UnescapeEdmField();
if (!arrayField.FieldsByName.TryGetValue(nestedEdmName, out var nestedField))
{
throw new NotSupportedException();
}
result[3] = nestedField.Id.ToString();
}
}
if (result.Count > 2)
{
result[2] = result[2].UnescapeEdmField();
}
if (result.Count > 0)
{
if (result[0].Equals("Data", StringComparison.CurrentCultureIgnoreCase))
{
if (inDraft)
{
result[0] = "dd";
}
else
{
result[0] = "do";
}
}
else
{
result[0] = PropertyMap[propertyNames[0]];
}
}
return result;
};
}
}
}

14
src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/AdaptionVisitor.cs

@ -26,22 +26,24 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Visitors
{ {
CompareFilter<ClrValue> result; CompareFilter<ClrValue> result;
var path = pathConverter(nodeIn.Path);
var value = nodeIn.Value.Value; var value = nodeIn.Value.Value;
if (value is Instant && if (value is Instant &&
!string.Equals(nodeIn.Path[0], "mt", StringComparison.OrdinalIgnoreCase) && !string.Equals(path[0], "mt", StringComparison.OrdinalIgnoreCase) &&
!string.Equals(nodeIn.Path[0], "ct", StringComparison.OrdinalIgnoreCase)) !string.Equals(path[0], "ct", StringComparison.OrdinalIgnoreCase))
{ {
result = new CompareFilter<ClrValue>(pathConverter(nodeIn.Path), nodeIn.Operator, value.ToString()); result = new CompareFilter<ClrValue>(path, nodeIn.Operator, value.ToString());
} }
else else
{ {
result = new CompareFilter<ClrValue>(pathConverter(nodeIn.Path), nodeIn.Operator, nodeIn.Value); result = new CompareFilter<ClrValue>(path, nodeIn.Operator, nodeIn.Value);
} }
if (result.Path.Count == 1 && result.Path[0] == "_id" && result.Value.Value is List<Guid> guidList) if (path.Count == 1 && path[0] == "_id" && result.Value.Value is List<Guid> guidList)
{ {
result = new CompareFilter<ClrValue>(nodeIn.Path, nodeIn.Operator, guidList.Select(x => x.ToString()).ToList()); result = new CompareFilter<ClrValue>(path, nodeIn.Operator, guidList.Select(x => x.ToString()).ToList());
} }
return result; return result;

71
src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/FilterFactory.cs

@ -8,11 +8,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver; using MongoDB.Driver;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.GenerateEdmSchema;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.MongoDb; using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.MongoDb.Queries; using Squidex.Infrastructure.MongoDb.Queries;
@ -24,13 +21,9 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Visitors
{ {
private static readonly FilterDefinitionBuilder<MongoContentEntity> Filter = Builders<MongoContentEntity>.Filter; private static readonly FilterDefinitionBuilder<MongoContentEntity> Filter = Builders<MongoContentEntity>.Filter;
private static readonly Dictionary<string, string> PropertyMap =
typeof(MongoContentEntity).GetProperties()
.ToDictionary(x => x.Name, x => x.GetCustomAttribute<BsonElementAttribute>()?.ElementName ?? x.Name, StringComparer.OrdinalIgnoreCase);
public static ClrQuery AdjustToModel(this ClrQuery query, Schema schema, bool useDraft) public static ClrQuery AdjustToModel(this ClrQuery query, Schema schema, bool useDraft)
{ {
var pathConverter = PathConverter(schema, useDraft); var pathConverter = Adapt.Path(schema, useDraft);
if (query.Filter != null) if (query.Filter != null)
{ {
@ -42,71 +35,13 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Visitors
return query; return query;
} }
public static FilterNode<ClrValue> AdjustToModel(this FilterNode<ClrValue> filterNode, Schema schema, bool inDraft) public static FilterNode<ClrValue> AdjustToModel(this FilterNode<ClrValue> filterNode, Schema schema, bool useDraft)
{ {
var pathConverter = PathConverter(schema, inDraft); var pathConverter = Adapt.Path(schema, useDraft);
return filterNode.Accept(new AdaptionVisitor(pathConverter)); return filterNode.Accept(new AdaptionVisitor(pathConverter));
} }
private static Func<PropertyPath, PropertyPath> PathConverter(Schema schema, bool inDraft)
{
return propertyNames =>
{
var result = new List<string>(propertyNames);
if (result.Count > 1)
{
var edmName = result[1].UnescapeEdmField();
if (!schema.FieldsByName.TryGetValue(edmName, out var field))
{
throw new NotSupportedException();
}
result[1] = field.Id.ToString();
if (field is IArrayField arrayField && result.Count > 3)
{
var nestedEdmName = result[3].UnescapeEdmField();
if (!arrayField.FieldsByName.TryGetValue(nestedEdmName, out var nestedField))
{
throw new NotSupportedException();
}
result[3] = nestedField.Id.ToString();
}
}
if (result.Count > 2)
{
result[2] = result[2].UnescapeEdmField();
}
if (result.Count > 0)
{
if (result[0].Equals("Data", StringComparison.CurrentCultureIgnoreCase))
{
if (inDraft)
{
result[0] = "dd";
}
else
{
result[0] = "do";
}
}
else
{
result[0] = PropertyMap[propertyNames[0]];
}
}
return result;
};
}
public static IFindFluent<MongoContentEntity, MongoContentEntity> ContentSort(this IFindFluent<MongoContentEntity, MongoContentEntity> cursor, ClrQuery query) public static IFindFluent<MongoContentEntity, MongoContentEntity> ContentSort(this IFindFluent<MongoContentEntity, MongoContentEntity> cursor, ClrQuery query)
{ {
return cursor.Sort(query.BuildSort<MongoContentEntity>()); return cursor.Sort(query.BuildSort<MongoContentEntity>());

22
src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/FilterVisitor.cs

@ -49,10 +49,16 @@ namespace Squidex.Infrastructure.MongoDb.Queries
{ {
var propertyName = nodeIn.Path.ToString(); var propertyName = nodeIn.Path.ToString();
var value = nodeIn.Value.Value;
switch (nodeIn.Operator) switch (nodeIn.Operator)
{ {
case CompareOperator.Empty: case CompareOperator.Empty:
return Filter.Or(Filter.Exists(propertyName, false), Filter.Eq(propertyName, default(T)), Filter.Eq(propertyName, string.Empty), Filter.Eq(propertyName, new T[0])); return Filter.Or(
Filter.Exists(propertyName, false),
Filter.Eq(propertyName, default(T)),
Filter.Eq(propertyName, string.Empty),
Filter.Eq(propertyName, new T[0]));
case CompareOperator.StartsWith: case CompareOperator.StartsWith:
return Filter.Regex(propertyName, BuildRegex(nodeIn, s => "^" + s)); return Filter.Regex(propertyName, BuildRegex(nodeIn, s => "^" + s));
case CompareOperator.Contains: case CompareOperator.Contains:
@ -60,19 +66,19 @@ namespace Squidex.Infrastructure.MongoDb.Queries
case CompareOperator.EndsWith: case CompareOperator.EndsWith:
return Filter.Regex(propertyName, BuildRegex(nodeIn, s => s + "$")); return Filter.Regex(propertyName, BuildRegex(nodeIn, s => s + "$"));
case CompareOperator.Equals: case CompareOperator.Equals:
return Filter.Eq(propertyName, nodeIn.Value.Value); return Filter.Eq(propertyName, value);
case CompareOperator.GreaterThan: case CompareOperator.GreaterThan:
return Filter.Gt(propertyName, nodeIn.Value.Value); return Filter.Gt(propertyName, value);
case CompareOperator.GreaterThanOrEqual: case CompareOperator.GreaterThanOrEqual:
return Filter.Gte(propertyName, nodeIn.Value.Value); return Filter.Gte(propertyName, value);
case CompareOperator.LessThan: case CompareOperator.LessThan:
return Filter.Lt(propertyName, nodeIn.Value.Value); return Filter.Lt(propertyName, value);
case CompareOperator.LessThanOrEqual: case CompareOperator.LessThanOrEqual:
return Filter.Lte(propertyName, nodeIn.Value.Value); return Filter.Lte(propertyName, value);
case CompareOperator.NotEquals: case CompareOperator.NotEquals:
return Filter.Ne(propertyName, nodeIn.Value.Value); return Filter.Ne(propertyName, value);
case CompareOperator.In: case CompareOperator.In:
return Filter.In(propertyName, ((IList)nodeIn.Value.Value).OfType<object>()); return Filter.In(propertyName, ((IList)value).OfType<object>());
} }
throw new NotSupportedException(); throw new NotSupportedException();

4
tests/Squidex.Domain.Apps.Entities.Tests/Contents/MongoDb/MongoDbQueryTests.cs

@ -86,7 +86,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.MongoDb
public void Should_make_query_with_lastModified() public void Should_make_query_with_lastModified()
{ {
var i = F(ClrFilter.Eq("lastModified", InstantPattern.General.Parse("1988-01-19T12:00:00Z").Value)); var i = F(ClrFilter.Eq("lastModified", InstantPattern.General.Parse("1988-01-19T12:00:00Z").Value));
var o = C("{ 'mt' : '1988-01-19T12:00:00Z' }"); var o = C("{ 'mt' : ISODate('1988-01-19T12:00:00Z') }");
Assert.Equal(o, i); Assert.Equal(o, i);
} }
@ -104,7 +104,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.MongoDb
public void Should_make_query_with_created() public void Should_make_query_with_created()
{ {
var i = F(ClrFilter.Eq("created", InstantPattern.General.Parse("1988-01-19T12:00:00Z").Value)); var i = F(ClrFilter.Eq("created", InstantPattern.General.Parse("1988-01-19T12:00:00Z").Value));
var o = C("{ 'ct' : '1988-01-19T12:00:00Z' }"); var o = C("{ 'ct' : ISODate('1988-01-19T12:00:00Z') }");
Assert.Equal(o, i); Assert.Equal(o, i);
} }

Loading…
Cancel
Save