Skip to content

Commit

Permalink
Rework of not: yes.
Browse files Browse the repository at this point in the history
Changes:
* Comparison operators: `{eq: 1, not: yes}` => `{notEqual: 1}`
* Logical: `{anyOf: [...], not: yes}` => `not { anyOf: [...]}

The `not` became more consistent with `allOf`/`anyOf` and compatible with [Tagged Type](https://github.com/graphql/graphql-spec/pull/733)/[oneOf input](graphql/graphql-spec#825). Also resolved ambiguity for Relation:

```
# this means "where count(...) != 2" now
relation: {
  where: {....}
  eq: 2
  not: yes
}
```
  • Loading branch information
LastDragon-ru committed May 2, 2021
1 parent ef6c97a commit 7609edd
Show file tree
Hide file tree
Showing 51 changed files with 1,226 additions and 646 deletions.
86 changes: 63 additions & 23 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,23 +61,23 @@ That's all, just search 😃
query {
# WHERE name = "LastDragon"
users(where: {
name: {eq: "LastDragon"}
name: {equal: "LastDragon"}
}) {
id
}

# WHERE name != "LastDragon"
users(where: {
name: {eq: "LastDragon", not: yes}
name: {notEqual: "LastDragon"}
}) {
id
}

# WHERE name = "LastDragon" or name = "Aleksei"
users(where: {
anyOf: [
{name: {eq: "LastDragon"}}
{name: {eq: "Aleksei"}}
{name: {equal: "LastDragon"}}
{name: {equal: "Aleksei"}}
]
}) {
id
Expand All @@ -86,8 +86,8 @@ query {
# WHERE NOT (name = "LastDragon" or name = "Aleksei")
users(where: {
anyOf: [
{name: {eq: "LastDragon"}}
{name: {eq: "Aleksei"}}
{name: {equal: "LastDragon"}}
{name: {equal: "Aleksei"}}
]
not: yes
}) {
Expand Down Expand Up @@ -118,7 +118,7 @@ query {
where: {
date: {between: {min: "2021-01-01", max: "2021-04-01"}}
}
eq: 2
equal: 2
}
}) {
id
Expand Down Expand Up @@ -154,7 +154,7 @@ input SearchByConditionCommentsQuery {
anyOf: [SearchByConditionCommentsQuery!]

"""Not."""
not: SearchByFlag
not: SearchByConditionCommentsQuery

"""Property condition."""
text: SearchByScalarString
Expand All @@ -177,7 +177,7 @@ input SearchByConditionUsersQuery {
anyOf: [SearchByConditionUsersQuery!]

"""Not."""
not: SearchByFlag
not: SearchByConditionUsersQuery

"""Property condition."""
id: SearchByScalarID
Expand All @@ -193,11 +193,30 @@ enum SearchByFlag {

"""Relation condition for input UsersQuery."""
input SearchByRelationUsersQuery {
"""Conditions for the related objects."""
"""
Conditions for the related objects (`has()`).
See also:
* https://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-existence
* https://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-absence
"""
where: SearchByConditionUsersQuery!

"""
Shortcut for `doesntHave()`, same as:
\```
where: [...]
lt: 1
\```
"""
not: Boolean! = false

"""Equal (`=`)."""
eq: Int
equal: Int

"""Not Equal (`!=`)."""
notEqual: Int

"""Less than (`<`)."""
lt: Int
Expand All @@ -210,22 +229,27 @@ input SearchByRelationUsersQuery {

"""Greater than or equal to (`>=`)."""
gte: Int

"""Not."""
not: SearchByFlag
}

input SearchByScalarDateOperatorBetween {
min: Date!
max: Date!
}

input SearchByScalarDateOperatorNotBetween {
min: Date!
max: Date!
}

"""
Available operators for scalar Date (only one operator allowed at a time).
"""
input SearchByScalarDateOrNull {
"""Equal (`=`)."""
eq: Date
equal: Date

"""Not Equal (`!=`)."""
notEqual: Date

"""Less than (`<`)."""
lt: Date
Expand All @@ -242,51 +266,67 @@ input SearchByScalarDateOrNull {
"""Within a set of values."""
in: [Date!]

"""Outside a set of values."""
notIn: [Date!]

"""Within a range."""
between: SearchByScalarDateOperatorBetween

"""Outside a range."""
notBetween: SearchByScalarDateOperatorNotBetween

"""Is NULL?"""
isNull: SearchByFlag

"""Not."""
not: SearchByFlag
"""Is NOT NULL?"""
isNotNull: SearchByFlag
}

"""
Available operators for scalar ID! (only one operator allowed at a time).
"""
input SearchByScalarID {
"""Equal (`=`)."""
eq: ID
equal: ID

"""Not Equal (`!=`)."""
notEqual: ID

"""Within a set of values."""
in: [ID!]

"""Not."""
not: SearchByFlag
"""Outside a set of values."""
notIn: [ID!]
}

"""
Available operators for scalar String! (only one operator allowed at a time).
"""
input SearchByScalarString {
"""Equal (`=`)."""
eq: String
equal: String

"""Not Equal (`!=`)."""
notEqual: String

"""Like."""
like: String

"""Not like."""
notLike: String

"""Within a set of values."""
in: [String!]

"""Not."""
not: SearchByFlag
"""Outside a set of values."""
notIn: [String!]
}

input UsersQuery {
id: ID!
name: String!
}

```

</details>
Expand Down
11 changes: 2 additions & 9 deletions src/SearchBy/AstManipulator.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,21 @@
use GraphQL\Language\AST\ScalarTypeDefinitionNode;
use GraphQL\Language\Parser;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use LastDragon_ru\LaraASP\GraphQL\AstManipulator as BaseAstManipulator;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Contracts\Operator;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Contracts\OperatorHasTypes;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Contracts\OperatorHasTypesForScalar;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Contracts\OperatorHasTypesForScalarNullable;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Contracts\OperatorNegationable;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Comparison\IsNotNull;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Comparison\IsNull;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Complex\Relation;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Not;
use Nuwave\Lighthouse\Schema\AST\ASTHelper;
use Nuwave\Lighthouse\Schema\AST\DocumentAST;

use function array_map;
use function array_merge;
use function implode;
use function is_a;
use function is_array;
use function is_null;
use function sprintf;
Expand Down Expand Up @@ -394,11 +391,7 @@ protected function getScalarOperators(string $scalar, bool $nullable): array {
// Add `null` for nullable
if ($nullable) {
$operators[] = IsNull::class;
}

// Add `not` for negationable
if (Arr::first($operators, static fn(string $o) => is_a($o, OperatorNegationable::class, true))) {
$operators[] = Not::class;
$operators[] = IsNotNull::class;
}

// Return
Expand Down
7 changes: 0 additions & 7 deletions src/SearchBy/Contracts/OperatorNegationable.php

This file was deleted.

19 changes: 17 additions & 2 deletions src/SearchBy/Directive.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,14 @@
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Comparison\LessThan;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Comparison\LessThanOrEqual;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Comparison\Like;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Comparison\NotBetween;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Comparison\NotEqual;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Comparison\NotIn;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Comparison\NotLike;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Complex\Relation;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Logical\AllOf;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Logical\AnyOf;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Not;
use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Logical\Not;
use Nuwave\Lighthouse\Schema\AST\DocumentAST;
use Nuwave\Lighthouse\Schema\Directives\BaseDirective;
use Nuwave\Lighthouse\Support\Contracts\ArgBuilderDirective;
Expand Down Expand Up @@ -52,39 +56,51 @@ class Directive extends BaseDirective implements ArgManipulator, ArgBuilderDirec
// Standard types
'ID' => [
Equal::class,
NotEqual::class,
In::class,
NotIn::class,
],
'Int' => [
Equal::class,
NotEqual::class,
LessThan::class,
LessThanOrEqual::class,
GreaterThan::class,
GreaterThanOrEqual::class,
In::class,
NotIn::class,
Between::class,
NotBetween::class,
],
'Float' => 'Int',
'Boolean' => [
Equal::class,
],
'String' => [
Equal::class,
NotEqual::class,
Like::class,
NotLike::class,
In::class,
NotIn::class,
],

// Special types
self::Enum => [
Equal::class,
NotEqual::class,
In::class,
NotIn::class,
],
self::Logic => [
AllOf::class,
AnyOf::class,
Not::class,
],
self::Relation => [
Relation::class,
Equal::class,
NotEqual::class,
LessThan::class,
LessThanOrEqual::class,
GreaterThan::class,
Expand Down Expand Up @@ -146,7 +162,6 @@ public function handleBuilder($builder, $value): EloquentBuilder|QueryBuilder {
return (new SearchBuilder(
$this->translator,
(new Collection($this->scalars))
->add(Not::class)
->flatten()
->unique()
->filter(static function (string $operator): bool {
Expand Down
33 changes: 16 additions & 17 deletions src/SearchBy/DirectiveTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,25 +70,24 @@ public function dataProviderHandleBuilder(): array {
'valid condition' => [
true,
[
'not' => 'yes',
'allOf' => [
[
'a' => [
'eq' => 1,
'not' => 'yes',
'not' => [
'allOf' => [
[
'a' => [
'notEqual' => 1,
],
],
],
[
'anyOf' => [
[
'a' => [
'eq' => 2,
[
'anyOf' => [
[
'a' => [
'equal' => 2,
],
],
],
[
'b' => [
'eq' => 3,
'not' => 'yes',
[
'b' => [
'notEqual' => 3,
],
],
],
],
Expand Down
Loading

0 comments on commit 7609edd

Please sign in to comment.