-
Notifications
You must be signed in to change notification settings - Fork 228
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Map range operations for NpgsqlRange<T> (#323)
- Loading branch information
1 parent
5655b1c
commit 502ce2a
Showing
5 changed files
with
947 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
#region License | ||
|
||
// The PostgreSQL License | ||
// | ||
// Copyright (C) 2016 The Npgsql Development Team | ||
// | ||
// Permission to use, copy, modify, and distribute this software and its | ||
// documentation for any purpose, without fee, and without a written | ||
// agreement is hereby granted, provided that the above copyright notice | ||
// and this paragraph and the following two paragraphs appear in all copies. | ||
// | ||
// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY | ||
// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, | ||
// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS | ||
// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF | ||
// THE POSSIBILITY OF SUCH DAMAGE. | ||
// | ||
// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, | ||
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | ||
// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS | ||
// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS | ||
// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | ||
|
||
#endregion | ||
|
||
using System; | ||
using NpgsqlTypes; | ||
|
||
namespace Npgsql.EntityFrameworkCore.PostgreSQL | ||
{ | ||
/// <summary> | ||
/// Provides extension methods for <see cref="NpgsqlRange{T}"/> supporting PostgreSQL translation. | ||
/// </summary> | ||
public static class NpgsqlRangeExtensions | ||
{ | ||
/// <summary> | ||
/// Determines whether a range contains a specified value. | ||
/// </summary> | ||
/// <param name="range">The range in which to locate the value.</param> | ||
/// <param name="value">The value to locate in the range.</param> | ||
/// <typeparam name="T">The type of the elements of <paramref name="range"/>.</typeparam> | ||
/// <returns> | ||
/// <value>true</value> if the range contains the specified value; otherwise, <value>false</value>. | ||
/// </returns> | ||
public static bool Contains<T>(this NpgsqlRange<T> range, T value) where T : IComparable<T> => throw new NotSupportedException(); | ||
|
||
/// <summary> | ||
/// Determines whether a range contains a specified range. | ||
/// </summary> | ||
/// <param name="a">The range in which to locate the specified range.</param> | ||
/// <param name="b">The specified range to locate in the range.</param> | ||
/// <typeparam name="T">The type of the elements of <paramref name="a"/>.</typeparam> | ||
/// <returns> | ||
/// <value>true</value> if the range contains the specified range; otherwise, <value>false</value>. | ||
/// </returns> | ||
public static bool Contains<T>(this NpgsqlRange<T> a, NpgsqlRange<T> b) where T : IComparable<T> => throw new NotSupportedException(); | ||
|
||
/// <summary> | ||
/// Determines whether a range is contained by a specified range. | ||
/// </summary> | ||
/// <param name="a">The specified range to locate in the range.</param> | ||
/// <param name="b">The range in which to locate the specified range.</param> | ||
/// <typeparam name="T">The type of the elements of <paramref name="a"/>.</typeparam> | ||
/// <returns> | ||
/// <value>true</value> if the range contains the specified range; otherwise, <value>false</value>. | ||
/// </returns> | ||
public static bool ContainedBy<T>(this NpgsqlRange<T> a, NpgsqlRange<T> b) where T : IComparable<T> => b.Contains(a); | ||
|
||
/// <summary> | ||
/// Determines whether a range overlaps another range. | ||
/// </summary> | ||
/// <param name="a">The first range.</param> | ||
/// <param name="b">The second range.</param> | ||
/// <typeparam name="T">The type of the elements of <paramref name="a"/>.</typeparam> | ||
/// <returns> | ||
/// <value>true</value> if the ranges overlap (share points in common); otherwise, <value>false</value>. | ||
/// </returns> | ||
public static bool Overlaps<T>(this NpgsqlRange<T> a, NpgsqlRange<T> b) where T : IComparable<T> => throw new NotSupportedException(); | ||
|
||
/// <summary> | ||
/// Determines whether a range is strictly to the left of another range. | ||
/// </summary> | ||
/// <param name="a">The first range.</param> | ||
/// <param name="b">The second range.</param> | ||
/// <typeparam name="T">The type of the elements of <paramref name="a"/>.</typeparam> | ||
/// <returns> | ||
/// <value>true</value> if the first range is strictly to the left of the second; otherwise, <value>false</value>. | ||
/// </returns> | ||
public static bool IsStrictlyLeftOf<T>(this NpgsqlRange<T> a, NpgsqlRange<T> b) where T : IComparable<T> => throw new NotSupportedException(); | ||
|
||
/// <summary> | ||
/// Determines whether a range is strictly to the right of another range. | ||
/// </summary> | ||
/// <param name="a">The first range.</param> | ||
/// <param name="b">The second range.</param> | ||
/// <typeparam name="T">The type of the elements of <paramref name="a"/>.</typeparam> | ||
/// <returns> | ||
/// <value>true</value> if the first range is strictly to the right of the second; otherwise, <value>false</value>. | ||
/// </returns> | ||
public static bool IsStrictlyRightOf<T>(this NpgsqlRange<T> a, NpgsqlRange<T> b) where T : IComparable<T> => throw new NotSupportedException(); | ||
|
||
/// <summary> | ||
/// Determines whether a range does not extend to the left of another range. | ||
/// </summary> | ||
/// <param name="a">The first range.</param> | ||
/// <param name="b">The second range.</param> | ||
/// <typeparam name="T">The type of the elements of <paramref name="a"/>.</typeparam> | ||
/// <returns> | ||
/// <value>true</value> if the first range does not extend to the left of the second; otherwise, <value>false</value>. | ||
/// </returns> | ||
public static bool DoesNotExtendLeftOf<T>(this NpgsqlRange<T> a, NpgsqlRange<T> b) where T : IComparable<T> => throw new NotSupportedException(); | ||
|
||
/// <summary> | ||
/// Determines whether a range does not extend to the right of another range. | ||
/// </summary> | ||
/// <param name="a">The first range.</param> | ||
/// <param name="b">The second range.</param> | ||
/// <typeparam name="T">The type of the elements of <paramref name="a"/>.</typeparam> | ||
/// <returns> | ||
/// <value>true</value> if the first range does not extend to the right of the second; otherwise, <value>false</value>. | ||
/// </returns> | ||
public static bool DoesNotExtendRightOf<T>(this NpgsqlRange<T> a, NpgsqlRange<T> b) where T : IComparable<T> => throw new NotSupportedException(); | ||
|
||
/// <summary> | ||
/// Determines whether a range is adjacent to another range. | ||
/// </summary> | ||
/// <param name="a">The first range.</param> | ||
/// <param name="b">The second range.</param> | ||
/// <typeparam name="T">The type of the elements of <paramref name="a"/>.</typeparam> | ||
/// <returns> | ||
/// <value>true</value> if the ranges are adjacent; otherwise, <value>false</value>. | ||
/// </returns> | ||
public static bool IsAdjacentTo<T>(this NpgsqlRange<T> a, NpgsqlRange<T> b) where T : IComparable<T> => throw new NotSupportedException(); | ||
|
||
/// <summary> | ||
/// Returns the set union, which means unique elements that appear in either of two ranges. | ||
/// </summary> | ||
/// <param name="a">The first range.</param> | ||
/// <param name="b">The second range.</param> | ||
/// <typeparam name="T">The type of the elements of <paramref name="a"/>.</typeparam> | ||
/// <returns> | ||
/// The unique elements that appear in either range. | ||
/// </returns> | ||
public static NpgsqlRange<T> Union<T>(this NpgsqlRange<T> a, NpgsqlRange<T> b) where T : IComparable<T> => throw new NotSupportedException(); | ||
|
||
/// <summary> | ||
/// Returns the set intersection, which means elements that appear in each of two ranges. | ||
/// </summary> | ||
/// <param name="a">The first range.</param> | ||
/// <param name="b">The second range.</param> | ||
/// <typeparam name="T">The type of the elements of <paramref name="a"/>.</typeparam> | ||
/// <returns> | ||
/// The elements that appear in both ranges. | ||
/// </returns> | ||
public static NpgsqlRange<T> Intersect<T>(this NpgsqlRange<T> a, NpgsqlRange<T> b) where T : IComparable<T> => throw new NotSupportedException(); | ||
|
||
/// <summary> | ||
/// Returns the set difference, which means the elements of one range that do not appear in a second range. | ||
/// </summary> | ||
/// <param name="a">The first range.</param> | ||
/// <param name="b">The second range.</param> | ||
/// <typeparam name="T">The type of the elements of <paramref name="a"/>.</typeparam> | ||
/// <returns> | ||
/// The elements that appear in the first range, but not the second range. | ||
/// </returns> | ||
public static NpgsqlRange<T> Except<T>(this NpgsqlRange<T> a, NpgsqlRange<T> b) where T : IComparable<T> => throw new NotSupportedException(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlRangeTranslator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#region License | ||
|
||
// The PostgreSQL License | ||
// | ||
// Copyright (C) 2016 The Npgsql Development Team | ||
// | ||
// Permission to use, copy, modify, and distribute this software and its | ||
// documentation for any purpose, without fee, and without a written | ||
// agreement is hereby granted, provided that the above copyright notice | ||
// and this paragraph and the following two paragraphs appear in all copies. | ||
// | ||
// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY | ||
// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, | ||
// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS | ||
// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF | ||
// THE POSSIBILITY OF SUCH DAMAGE. | ||
// | ||
// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, | ||
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | ||
// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS | ||
// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS | ||
// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | ||
|
||
#endregion | ||
|
||
using System.Linq.Expressions; | ||
using JetBrains.Annotations; | ||
using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; | ||
using Npgsql.EntityFrameworkCore.PostgreSQL.Query.Expressions.Internal; | ||
|
||
namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Internal | ||
{ | ||
/// <summary> | ||
/// Provides translation services for PostgreSQL range operators. | ||
/// </summary> | ||
/// <remarks> | ||
/// See: https://www.postgresql.org/docs/current/static/functions-range.html | ||
/// </remarks> | ||
public class NpgsqlRangeTranslator : IMethodCallTranslator | ||
{ | ||
/// <inheritdoc /> | ||
[CanBeNull] | ||
public Expression Translate(MethodCallExpression expression) | ||
{ | ||
switch (expression.Method.Name) | ||
{ | ||
case nameof(NpgsqlRangeExtensions.Contains): | ||
return new CustomBinaryExpression(expression.Arguments[0], expression.Arguments[1], "@>", typeof(bool)); | ||
|
||
case nameof(NpgsqlRangeExtensions.ContainedBy): | ||
return new CustomBinaryExpression(expression.Arguments[0], expression.Arguments[1], "<@", typeof(bool)); | ||
|
||
case nameof(NpgsqlRangeExtensions.Overlaps): | ||
return new CustomBinaryExpression(expression.Arguments[0], expression.Arguments[1], "&&", typeof(bool)); | ||
|
||
case nameof(NpgsqlRangeExtensions.IsStrictlyLeftOf): | ||
return new CustomBinaryExpression(expression.Arguments[0], expression.Arguments[1], "<<", typeof(bool)); | ||
|
||
case nameof(NpgsqlRangeExtensions.IsStrictlyRightOf): | ||
return new CustomBinaryExpression(expression.Arguments[0], expression.Arguments[1], ">>", typeof(bool)); | ||
|
||
case nameof(NpgsqlRangeExtensions.DoesNotExtendRightOf): | ||
return new CustomBinaryExpression(expression.Arguments[0], expression.Arguments[1], "&<", typeof(bool)); | ||
|
||
case nameof(NpgsqlRangeExtensions.DoesNotExtendLeftOf): | ||
return new CustomBinaryExpression(expression.Arguments[0], expression.Arguments[1], "&>", typeof(bool)); | ||
|
||
case nameof(NpgsqlRangeExtensions.IsAdjacentTo): | ||
return new CustomBinaryExpression(expression.Arguments[0], expression.Arguments[1], "-|-", typeof(bool)); | ||
|
||
case nameof(NpgsqlRangeExtensions.Union): | ||
return new CustomBinaryExpression(expression.Arguments[0], expression.Arguments[1], "+", expression.Arguments[0].Type); | ||
|
||
case nameof(NpgsqlRangeExtensions.Intersect): | ||
return new CustomBinaryExpression(expression.Arguments[0], expression.Arguments[1], "*", expression.Arguments[0].Type); | ||
|
||
case nameof(NpgsqlRangeExtensions.Except): | ||
return new CustomBinaryExpression(expression.Arguments[0], expression.Arguments[1], "-", expression.Arguments[0].Type); | ||
|
||
default: | ||
return null; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.