Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/create-coverage-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ on:
- "**"
pull_request:
branches:
- "main"
- "master"
paths:
- "src/**.php"
- "tests/**.php"
Expand Down
32 changes: 31 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,37 @@ Versioning <https://semver.org/spec/v2.0.0.html>`__.
:depth: 1

`[Unreleased] <https://campoint.github.io/postgrest-php/latest>`_
-----------------------------------------------------------
-----------------------------------------------------------------

Added
~~~~~

- Support for complex logic conditions using and/or (`#4 <https://github.com/Campoint/postgrest-php/pull/4>`_)

Changed
~~~~~~~

- n/a

Deprecated
~~~~~~~~~~

- n/a

Removed
~~~~~~~

- n/a

Fixed
~~~~~

- n/a

Security
~~~~~~~~

- n/a

`[0.0.1] <https://campoint.github.io/postgrest-php/0.0.1>`_ - 2023-07-24
------------------------------------------------------------------------
Expand Down
22 changes: 22 additions & 0 deletions docs/guides/request-builder/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,28 @@ pass it to the ``run()`` method of the client.

$response = $client->run($query);

Complex logic conditions
~~~~~~~~~~~~~~~~~~~~~~~~

The ``PostgrestRequestBuilder`` supports complex logic conditions using ``and``/ ``or``.
Unfortunately, when using ``and``/ ``or`` the ``PostgrestRequestBuilder`` will not be able to,
escape the values for you. You will have to escape the values yourself.

.. code:: php

$query = $client->from('schema_name', 'table_name')
->select('*')
->or(
(new LogicOperatorCondition('a', FilterOperator::EQUAL, 42)),
(new LogicOperatorCondition('b', FilterOperator::LESS_THAN, 2.0, negate: true)),
// escape strings yourself
(new LogicOperatorCondition('c', FilterOperator::IN, '("foo bar",bar)')),
);

Nested complex logic conditions are not supported using the LogicOperatorCondition class.
You will need to build the string yourself. You can implement your own logic condition class
which implements the ``Stringable`` interface, as the functions ``or()`` and ``and()`` accept this interface.

Exceptions
----------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*
* @link https://postgrest.org/en/stable/references/api/tables_views.html#operators
*/
enum Operator: string
enum FilterOperators: string
{
case EQUAL = 'eq';
case GREATER_THAN = 'gt';
Expand All @@ -36,9 +36,4 @@ enum Operator: string
case NOT_EXTEND_TO_RIGHT = 'nxr';
case NOT_EXTEND_TO_LEFT = 'nxl';
case ADJACENT = 'adj';
case NOT = 'not';
case OR = 'or';
case AND = 'and';
case ALL = 'all';
case ANY = 'any';
}
12 changes: 12 additions & 0 deletions src/RequestBuilder/Enums/LogicOperators.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace PostgrestPhp\RequestBuilder\Enums;

enum LogicOperators: string
{
case NOT = 'not';
case OR = 'or';
case AND = 'and';
}
11 changes: 11 additions & 0 deletions src/RequestBuilder/Enums/OperatorModifier.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace PostgrestPhp\RequestBuilder\Enums;

enum OperatorModifier: string
{
case ALL = 'all';
case ANY = 'any';
}
2 changes: 2 additions & 0 deletions src/RequestBuilder/Exceptions/FilterLogicException.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class FilterLogicException extends Exception

final public const DUPLICATE_RESOLUTION_REQUIRED = 'Duplicate resolution required for upsert()';

final public const INVALID_CONDITION = 'Cannot use modifier and language at the same time';

/**
* Create a new FilterLogicException.
*
Expand Down
36 changes: 36 additions & 0 deletions src/RequestBuilder/LogicOperatorCondition.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace PostgrestPhp\RequestBuilder;

use PostgrestPhp\RequestBuilder\Enums\FilterOperators;
use PostgrestPhp\RequestBuilder\Enums\LogicOperators;
use PostgrestPhp\RequestBuilder\Enums\OperatorModifier;
use PostgrestPhp\RequestBuilder\Exceptions\FilterLogicException;
use Stringable;

class LogicOperatorCondition implements Stringable
{
public function __construct(
private string $column,
private FilterOperators $operator,
private string|int|float $value,
private bool $negate = false,
private ?OperatorModifier $modifier = null,
private ?string $language = null,
) {
if ($this->modifier && $this->language) {
throw new FilterLogicException(FilterLogicException::INVALID_CONDITION);
}
}

public function __toString()
{
$operator = $this->operator->value;
$operator = $this->negate ? sprintf('%s.%s', LogicOperators::NOT->value, $operator) : $operator;
$operator = $this->modifier ? sprintf('%s(%s)', $operator, $this->modifier->value) : $operator;
$operator = $this->language ? sprintf('%s(%s)', $operator, $this->language) : $operator;
return sprintf('%s.%s.%s', $this->column, $operator, strval($this->value));
}
}
26 changes: 13 additions & 13 deletions src/RequestBuilder/Traits/ArrayRangeOperators.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace PostgrestPhp\RequestBuilder\Traits;

use PostgrestPhp\RequestBuilder\Enums\Operator;
use PostgrestPhp\RequestBuilder\Enums\FilterOperators;
use PostgrestPhp\RequestBuilder\Enums\OverlapType;
use PostgrestPhp\RequestBuilder\Exceptions\NotUnifiedValuesException;
use PostgrestPhp\RequestBuilder\PostgrestRequestBuilder;
Expand All @@ -25,7 +25,7 @@ trait ArrayRangeOperators
*/
public function cs(string $columnName, array $value): PostgrestRequestBuilder
{
return $this->arrayHelper(Operator::CONTAINS, $columnName, $value, ['{', '}']);
return $this->arrayHelper(FilterOperators::CONTAINS, $columnName, $value, ['{', '}']);
}

/**
Expand All @@ -39,7 +39,7 @@ public function cs(string $columnName, array $value): PostgrestRequestBuilder
*/
public function cd(string $columnName, array $value): PostgrestRequestBuilder
{
return $this->arrayHelper(Operator::CONTAINED_IN, $columnName, $value, ['{', '}']);
return $this->arrayHelper(FilterOperators::CONTAINED_IN, $columnName, $value, ['{', '}']);
}

/**
Expand All @@ -60,7 +60,7 @@ public function ov(
if (! $this->helper::checkUnifiedValueTypes($value)) {
throw new NotUnifiedValuesException(NotUnifiedValuesException::NOT_UNIFIED_ARRAY);
}
$operator = $this->negateOperator(Operator::OVERLAP, $this->negateNextFilter);
$operator = $this->negateOperator(FilterOperators::OVERLAP, $this->negateNextFilter);
$transformedValue = $this->helper::implodeWithBraces($value, $overlapType->value[0], $overlapType->value[1]);
return $this->filterRawColumn($columnName, $operator, $transformedValue);
}
Expand All @@ -77,7 +77,7 @@ public function ov(
*/
public function sl(string $columnName, int|float $start, int|float $end): PostgrestRequestBuilder
{
return $this->rangeHelper(Operator::STRICTLY_LEFT_OF, $columnName, $start, $end);
return $this->rangeHelper(FilterOperators::STRICTLY_LEFT_OF, $columnName, $start, $end);
}

/**
Expand All @@ -92,7 +92,7 @@ public function sl(string $columnName, int|float $start, int|float $end): Postgr
*/
public function sr(string $columnName, int|float $start, int|float $end): PostgrestRequestBuilder
{
return $this->rangeHelper(Operator::STRICTLY_RIGHT_OF, $columnName, $start, $end);
return $this->rangeHelper(FilterOperators::STRICTLY_RIGHT_OF, $columnName, $start, $end);
}

/**
Expand All @@ -107,7 +107,7 @@ public function sr(string $columnName, int|float $start, int|float $end): Postgr
*/
public function nxr(string $columnName, int|float $start, int|float $end): PostgrestRequestBuilder
{
return $this->rangeHelper(Operator::NOT_EXTEND_TO_RIGHT, $columnName, $start, $end);
return $this->rangeHelper(FilterOperators::NOT_EXTEND_TO_RIGHT, $columnName, $start, $end);
}

/**
Expand All @@ -122,7 +122,7 @@ public function nxr(string $columnName, int|float $start, int|float $end): Postg
*/
public function nxl(string $columnName, int|float $start, int|float $end): PostgrestRequestBuilder
{
return $this->rangeHelper(Operator::NOT_EXTEND_TO_LEFT, $columnName, $start, $end);
return $this->rangeHelper(FilterOperators::NOT_EXTEND_TO_LEFT, $columnName, $start, $end);
}

/**
Expand All @@ -137,21 +137,21 @@ public function nxl(string $columnName, int|float $start, int|float $end): Postg
*/
public function adj(string $columnName, int|float $start, int|float $end): PostgrestRequestBuilder
{
return $this->rangeHelper(Operator::ADJACENT, $columnName, $start, $end);
return $this->rangeHelper(FilterOperators::ADJACENT, $columnName, $start, $end);
}

/**
* Array operator helper.
* Prevents code duplication.
* @param Operator $op The operator to use.
* @param FilterOperators $op The operator to use.
* @param string $columnName The name of the column.
* @param string[]|int[]|float[] $value The value to use.
* @param string[] $braces The braces to use.
* @return PostgrestRequestBuilder The PostgrestRequestBuilder instance.
* @throws NotUnifiedValuesException If the value types are not unified.
*/
private function arrayHelper(
Operator $op,
FilterOperators $op,
string $columnName,
array $value,
array $braces,
Expand All @@ -167,15 +167,15 @@ private function arrayHelper(
/**
* Range operator helper.
* Prevents code duplication.
* @param Operator $op The operator to use.
* @param FilterOperators $op The operator to use.
* @param string $columnName The name of the column.
* @param int|float $start The start value to use.
* @param int|float $end The end value to use.
* @return PostgrestRequestBuilder The PostgrestRequestBuilder instance.
* @throws NotUnifiedValuesException If the start and end types are not unified.
*/
private function rangeHelper(
Operator $op,
FilterOperators $op,
string $columnName,
int|float $start,
int|float $end,
Expand Down
12 changes: 6 additions & 6 deletions src/RequestBuilder/Traits/EqualityOperators.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace PostgrestPhp\RequestBuilder\Traits;

use PostgrestPhp\RequestBuilder\Enums\FilterOperators;
use PostgrestPhp\RequestBuilder\Enums\IsCheck;
use PostgrestPhp\RequestBuilder\Enums\Operator;
use PostgrestPhp\RequestBuilder\Exceptions\FilterLogicException;
use PostgrestPhp\RequestBuilder\Exceptions\NotUnifiedValuesException;
use PostgrestPhp\RequestBuilder\PostgrestRequestBuilder;
Expand All @@ -29,7 +29,7 @@ public function eq(string $columnName, string|int|float ...$value): PostgrestReq
{
$numValues = count($value);
$this->checkOperatorModifier($numValues, $value);
$operator = $this->negateOperator(Operator::EQUAL, $this->negateNextFilter);
$operator = $this->negateOperator(FilterOperators::EQUAL, $this->negateNextFilter);
if ($numValues > 1) {
$operator = $this->applyOperatorModifier($operator);
$transformedValue = $this->helper::implodeWithBraces($value, '{', '}');
Expand All @@ -49,7 +49,7 @@ public function eq(string $columnName, string|int|float ...$value): PostgrestReq
*/
public function neq(string $columnName, string|int|float $value): PostgrestRequestBuilder
{
$operator = $this->negateOperator(Operator::NOT_EQUAL, $this->negateNextFilter);
$operator = $this->negateOperator(FilterOperators::NOT_EQUAL, $this->negateNextFilter);
return $this->filterRawColumn($columnName, $operator, $this->helper::escapeString($value));
}

Expand All @@ -63,7 +63,7 @@ public function neq(string $columnName, string|int|float $value): PostgrestReque
*/
public function is(string $columnName, IsCheck $value): PostgrestRequestBuilder
{
$operator = $this->negateOperator(Operator::IS, $this->negateNextFilter);
$operator = $this->negateOperator(FilterOperators::IS, $this->negateNextFilter);
return $this->filterRawColumn($columnName, $operator, $value->value);
}

Expand All @@ -81,7 +81,7 @@ public function in(string $columnName, string|int|float ...$value): PostgrestReq
if (! $this->helper::checkUnifiedValueTypes($value)) {
throw new NotUnifiedValuesException(NotUnifiedValuesException::NOT_UNIFIED_ARRAY);
}
$operator = $this->negateOperator(Operator::IN, $this->negateNextFilter);
$operator = $this->negateOperator(FilterOperators::IN, $this->negateNextFilter);
$transformedValue = $this->helper::implodeWithBraces($value, '(', ')');
return $this->filterRawColumn($columnName, $operator, $transformedValue);
}
Expand All @@ -96,7 +96,7 @@ public function in(string $columnName, string|int|float ...$value): PostgrestReq
*/
public function isdistinct(string $columnName, string|int|float $value): PostgrestRequestBuilder
{
$operator = $this->negateOperator(Operator::IS_DISTINCT_FROM, $this->negateNextFilter);
$operator = $this->negateOperator(FilterOperators::IS_DISTINCT_FROM, $this->negateNextFilter);
return $this->filterRawColumn($columnName, $operator, $this->helper::escapeString($value));
}
}
1 change: 1 addition & 0 deletions src/RequestBuilder/Traits/FilterOperators.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ trait FilterOperators
{
use ModifierOperators;
use EqualityOperators;
use LogicalOperators;
use GreaterLessOperators;
use PatternMatchingOperators;
use FullTextSearchOperators;
Expand Down
10 changes: 5 additions & 5 deletions src/RequestBuilder/Traits/FullTextSearchOperators.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace PostgrestPhp\RequestBuilder\Traits;

use PostgrestPhp\RequestBuilder\Enums\Operator;
use PostgrestPhp\RequestBuilder\Enums\FilterOperators;
use PostgrestPhp\RequestBuilder\PostgrestRequestBuilder;

/**
Expand All @@ -23,7 +23,7 @@ trait FullTextSearchOperators
*/
public function fts(string $columnName, string $value, ?string $language = null): PostgrestRequestBuilder
{
$operator = $this->negateOperator(Operator::FULL_TEXT_SEARCH, $this->negateNextFilter);
$operator = $this->negateOperator(FilterOperators::FULL_TEXT_SEARCH, $this->negateNextFilter);
return $this->ftsHelper($operator, $columnName, $value, $language);
}

Expand All @@ -38,7 +38,7 @@ public function fts(string $columnName, string $value, ?string $language = null)
*/
public function plfts(string $columnName, string $value, ?string $language = null): PostgrestRequestBuilder
{
$operator = $this->negateOperator(Operator::PLAIN_FULL_TEXT_SEARCH, $this->negateNextFilter);
$operator = $this->negateOperator(FilterOperators::PLAIN_FULL_TEXT_SEARCH, $this->negateNextFilter);
return $this->ftsHelper($operator, $columnName, $value, $language);
}

Expand All @@ -53,7 +53,7 @@ public function plfts(string $columnName, string $value, ?string $language = nul
*/
public function phfts(string $columnName, string $value, ?string $language = null): PostgrestRequestBuilder
{
$operator = $this->negateOperator(Operator::PHRASE_FULL_TEXT_SEARCH, $this->negateNextFilter);
$operator = $this->negateOperator(FilterOperators::PHRASE_FULL_TEXT_SEARCH, $this->negateNextFilter);
return $this->ftsHelper($operator, $columnName, $value, $language);
}

Expand All @@ -68,7 +68,7 @@ public function phfts(string $columnName, string $value, ?string $language = nul
*/
public function wfts(string $columnName, string $value, ?string $language = null): PostgrestRequestBuilder
{
$operator = $this->negateOperator(Operator::WEBSEARCH_FULL_TEXT_SEARCH, $this->negateNextFilter);
$operator = $this->negateOperator(FilterOperators::WEBSEARCH_FULL_TEXT_SEARCH, $this->negateNextFilter);
return $this->ftsHelper($operator, $columnName, $value, $language);
}

Expand Down
Loading