Skip to content

Commit

Permalink
New filters and fixes (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerych1984 committed Oct 27, 2021
1 parent 5953675 commit 88e119b
Show file tree
Hide file tree
Showing 15 changed files with 358 additions and 43 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
## 1.0.0 under development

- Initial release.

42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,47 @@ $equalsTableOne = (new Equals('id', 1, 'table_one'))->withIgnoreNull(true);
$equalsTableTwo = (new Equals('id', 100, 'table_two'))->withIgnoreNull(true);
```

Others filters/processors will be added at the nearest time.
## Current filters/processors
### Compare
* Equals - =
* NotEquals - !=
* GreaterThan - >
* GreaterThanOrEqual - >=
* In
* LessThan - <
* LessThanOrEqual - <=
* Not
* Like\ILIke
* Exists
* Between

#### Filter "Like" or "ILike"
This filters has methods `withBoth`, `withoutBoth`, `withStart`, `withoutStart`, `withEnd`, `withoutEnd`
```php

$filter = new Like('column', 'value');
$dataReader = (new QueryDataReader($query))->withFilter($filter);
//column LIKE '%value%'

$filter = (new Like('column', 'value'))->withoutStart();
$dataReader = (new QueryDataReader($query))->withFilter($filter);
//column LIKE 'value%'

$filter = (new Like('column', 'value'))->withoutEnd();
$dataReader = (new QueryDataReader($query))->withFilter($filter);
//column LIKE '%value'

```

#### FIlter "Exists"
Takes only one argument with type of`Yiisoft\Db\Query\Query`

#### Filter "Not"
Takes only one argument with type of`Yiisoft\Data\Reader\Filter\FilterInterface`

### Group
* All - and
* Any - or

## Testing

Expand Down
60 changes: 60 additions & 0 deletions src/Filter/Between.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Data\Db\Filter;

use InvalidArgumentException;

final class Between extends CompareFilter
{
/**
* @param mixed $column
*/
public function __construct($column, ?array $value, ?string $table = null)
{
if (is_array($value) && count($value) !== 2) {
throw new InvalidArgumentException('Value must be a [from, to] array.');
}

parent::__construct($column, $value, $table);
}

public static function getOperator(): string
{
return 'between';
}

/**
* @param mixed $value
*/
private static function isEmpty($value): bool
{
return $value !== null && $value !== '';
}

public function toArray(): array
{
if (is_array($this->value)) {
$value = $this->value;
$start = array_shift($value);
$end = array_pop($value);

if (!self::isEmpty($start) && !self::isEmpty($end)) {
return [self::getOperator(), $this->column, $start, $end];
}

if (!self::isEmpty($start)) {
return [GreaterThanOrEqual::getOperator(), $this->column, $start];
}

if (!self::isEmpty($end)) {
return [LessThanOrEqual::getOperator(), $this->column, $end];
}

return [];
}

return parent::toArray();
}
}
23 changes: 18 additions & 5 deletions src/Filter/CompareFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@

namespace Yiisoft\Data\Db\Filter;

use InvalidArgumentException;
use Yiisoft\Data\Reader\Filter\FilterInterface;
use Yiisoft\Db\Expression\ExpressionInterface;

abstract class CompareFilter implements FilterInterface
{
protected string $column;
/**
* @var ExpressionInterface|string
*/
protected $column;

/**
* @var array|bool|float|int|string|null
Expand All @@ -21,16 +26,24 @@ abstract class CompareFilter implements FilterInterface
protected bool $ignoreNull = false;

/**
* @param mixed $column
* @param mixed $value
*/
public function __construct(string $column, $value, ?string $table = null)
public function __construct($column, $value, ?string $table = null)
{
$this->value = $value;

if ($table) {
$this->column = $table . '.' . $column;
} else {
if ($column instanceof ExpressionInterface) {
$this->column = $column;
} elseif (is_string($column)) {
if ($table) {
$this->column = $table . '.' . $column;
} else {
$this->column = $column;
}
} else {
$type = \is_object($column) ? \get_class($column) : \gettype($column);
throw new InvalidArgumentException('Column must be string or instance of "' . ExpressionInterface::class . '". "' . $type .'" given.');
}
}

Expand Down
14 changes: 11 additions & 3 deletions src/Filter/Exists.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,24 @@
namespace Yiisoft\Data\Db\Filter;

use Yiisoft\Db\Query\Query;
use Yiisoft\Data\Reader\Filter\FilterInterface;

final class Exists extends CompareFilter
final class Exists implements FilterInterface
{
public function __construct(string $column, ?Query $value, ?string $table = null)
private Query $query;

public function __construct(Query $query)
{
parent::__construct($column, $value, $table);
$this->query = $query;
}

public static function getOperator(): string
{
return 'exists';
}

public function toArray(): array
{
return [self::getOperator(), $this->query];
}
}
13 changes: 13 additions & 0 deletions src/Filter/ILike.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Data\Db\Filter;

final class ILike extends Like
{
public static function getOperator(): string
{
return 'ilike';
}
}
16 changes: 13 additions & 3 deletions src/Filter/Like.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ public static function getOperator(): string
return FilterLike::getOperator();
}

public function withBoth(): self
{
return $this->withStart()->withEnd();
}

public function withoutBoth(): self
{
return $this->withoutStart()->withoutEnd();
}

public function withStart(): self
{
if ($this->start === true) {
Expand Down Expand Up @@ -76,11 +86,11 @@ public function toArray(): array
}

if (!$this->start && !$this->end) {
return [self::getOperator(), $this->column, $this->value, false];
return [static::getOperator(), $this->column, $this->value, false];
}

$value = $this->start ? $this->value . '%' : '%' . $this->value;
$value = $this->start ? '%' . $this->value : $this->value . '%';

return [self::getOperator(), $this->column, $value, false];
return [static::getOperator(), $this->column, $value, false];
}
}
45 changes: 45 additions & 0 deletions src/Filter/Not.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Data\Db\Filter;

use Yiisoft\Data\Reader\Filter\Not as FilterNot;
use Yiisoft\Data\Reader\Filter\FilterInterface;

final class Not implements FilterInterface
{
private FilterInterface $filter;

public function __construct(FilterInterface $filter)
{
$this->filter = $filter;
}

public static function getOperator(): string
{
return FilterNot::getOperator();
}

public function toArray(): array
{
$array = $this->filter->toArray();

if ($array === []) {
return [];
}

switch ($array[0]) {
case 'IS':
$array[0] .= ' ' . self::getOperator();
break;
case Exists::getOperator(): case In::getOperator(): case Between::getOperator():
$array[0] = self::getOperator() . ' ' . $array[0];
break;
default:
$array = [self::getOperator(), $array];
}

return $array;
}
}
37 changes: 37 additions & 0 deletions src/Filter/NotEquals.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Data\Db\Filter;

use RuntimeException;
use Stringable;

final class NotEquals extends CompareFilter
{
public static function getOperator(): string
{
return '!=';
}

public function toArray(): array
{
if ($this->value === null) {
if ($this->ignoreNull) {
return [];
}

if (is_string($this->column)) {
return ['NOT', [$this->column => null]];
}

if ($this->column instanceof Stringable) {
return ['NOT', [$this->column->__toString() => null]];
}

throw new RuntimeException();
}

return [self::getOperator(), $this->column, $this->value];
}
}
15 changes: 15 additions & 0 deletions src/Processor/Between.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Data\Db\Processor;

use Yiisoft\Data\Db\Filter\Between as FilterBetween;

class Between extends CompareProcessor
{
public function getOperator(): string
{
return FilterBetween::getOperator();
}
}
16 changes: 16 additions & 0 deletions src/Processor/ILike.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Data\Db\Processor;

use Yiisoft\Data\Db\Filter\ILike as ILikeFilter;
use Yiisoft\Data\Db\Processor\CompareProcessor;

class ILike extends CompareProcessor
{
public function getOperator(): string
{
return ILikeFilter::getOperator();
}
}
15 changes: 15 additions & 0 deletions src/Processor/Not.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Data\Db\Processor;

use Yiisoft\Data\Db\Filter\Not as FilterNot;

final class Not extends CompareProcessor
{
public function getOperator(): string
{
return FilterNot::getOperator();
}
}
15 changes: 15 additions & 0 deletions src/Processor/NotEquals.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Data\Db\Processor;

use Yiisoft\Data\Db\Filter\NotEquals as NotEqualsFilter;

final class NotEquals extends CompareProcessor
{
public function getOperator(): string
{
return NotEqualsFilter::getOperator();
}
}

0 comments on commit 88e119b

Please sign in to comment.