Skip to content

Commit

Permalink
Added and/or/andNot/orNot to ScalarFunctionsChain (#1378)
Browse files Browse the repository at this point in the history
  • Loading branch information
norberttech authored Jan 16, 2025
1 parent 6e51340 commit 39f3d51
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 34 deletions.
29 changes: 22 additions & 7 deletions src/core/etl/src/Flow/ETL/Function/All.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,32 @@

use Flow\ETL\Row;

final class All extends ScalarFunctionChain implements CompositeScalarFunction
final readonly class All implements ScalarFunction
{
/**
* @var array<ScalarFunction>
*/
private readonly array $refs;
private array $functions;

public function __construct(
ScalarFunction ...$refs,
ScalarFunction ...$functions,
) {
$this->refs = $refs;
$this->functions = $functions;
}

public function and(ScalarFunction $scalarFunction) : self
{
return new self(...$this->functions, ...[$scalarFunction]);
}

public function andNot(ScalarFunction $scalarFunction) : self
{
return new self(...$this->functions, ...[new Not($scalarFunction)]);
}

public function eval(Row $row) : mixed
{
foreach ($this->refs as $ref) {
foreach ($this->functions as $ref) {
if (!$ref->eval($row)) {
return false;
}
Expand All @@ -30,8 +40,13 @@ public function eval(Row $row) : mixed
return true;
}

public function functions() : array
public function or(ScalarFunction $scalarFunction) : Any
{
return new Any(...$this->functions, ...[$scalarFunction]);
}

public function orNot(ScalarFunction $scalarFunction) : Any
{
return $this->refs;
return new Any(...$this->functions, ...[new Not($scalarFunction)]);
}
}
32 changes: 22 additions & 10 deletions src/core/etl/src/Flow/ETL/Function/Any.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,32 @@

use Flow\ETL\Row;

final class Any extends ScalarFunctionChain implements CompositeScalarFunction
final readonly class Any implements ScalarFunction
{
/**
* @var array<ScalarFunction>
*/
private readonly array $refs;
private array $functions;

public function __construct(
ScalarFunction ...$values,
ScalarFunction ...$functions,
) {
$this->refs = $values;
$this->functions = $functions;
}

public function and(ScalarFunction $scalarFunction) : All
{
return new All(...$this->functions, ...[$scalarFunction]);
}

public function andNot(ScalarFunction $scalarFunction) : All
{
return new All(...$this->functions, ...[new Not($scalarFunction)]);
}

public function eval(Row $row) : mixed
{
foreach ($this->refs as $ref) {
foreach ($this->functions as $ref) {
if ($ref->eval($row)) {
return true;
}
Expand All @@ -30,11 +40,13 @@ public function eval(Row $row) : mixed
return false;
}

/**
* @return array<ScalarFunction>
*/
public function functions() : array
public function or(ScalarFunction $scalarFunction) : self
{
return new self(...$this->functions, ...[$scalarFunction]);
}

public function orNot(ScalarFunction $scalarFunction) : self
{
return $this->refs;
return new self(...$this->functions, ...[new Not($scalarFunction)]);
}
}
13 changes: 0 additions & 13 deletions src/core/etl/src/Flow/ETL/Function/CompositeScalarFunction.php

This file was deleted.

20 changes: 20 additions & 0 deletions src/core/etl/src/Flow/ETL/Function/ScalarFunctionChain.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@

abstract class ScalarFunctionChain implements ScalarFunction
{
public function and(ScalarFunction $function) : All
{
return new All($this, $function);
}

public function andNot(ScalarFunction $function) : All
{
return new All($this, new Not($function));
}

public function arrayGet(ScalarFunction|string $path) : self
{
return new ArrayGet($this, $path);
Expand Down Expand Up @@ -319,6 +329,16 @@ public function onEach(ScalarFunction $function, ScalarFunction|bool $preserveKe
return new OnEach($this, $function, $preserveKeys);
}

public function or(ScalarFunction $function) : Any
{
return new Any($this, $function);
}

public function orNot(ScalarFunction $function) : Any
{
return new Any($this, new Not($function));
}

public function plus(ScalarFunction|int|float $ref) : self
{
return new Plus($this, $ref);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Flow\ETL\Tests\Integration\Function;

use function Flow\ETL\DSL\{all, from_array, lit, ref, to_memory, when};
use function Flow\ETL\DSL\{from_array, lit, ref, to_memory, when};
use Flow\ETL\Flow;
use Flow\ETL\Memory\ArrayMemory;
use Flow\ETL\Tests\FlowTestCase;
Expand All @@ -27,7 +27,7 @@ public function test_all_cases_found() : void
->withEntry(
'result',
when(
all(ref('id')->isEven(), ref('array')->exists()),
ref('id')->isEven()->and(ref('array')->exists()),
lit('found'),
lit('not found')
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Flow\ETL\Tests\Integration\Function;

use function Flow\ETL\DSL\{any, from_array, lit, ref, to_memory, when};
use function Flow\ETL\DSL\{from_array, lit, ref, to_memory, when};
use Flow\ETL\Flow;
use Flow\ETL\Memory\ArrayMemory;
use Flow\ETL\Tests\FlowTestCase;
Expand All @@ -27,7 +27,7 @@ public function test_any_case_found() : void
->withEntry(
'result',
when(
any(ref('id')->isEven(), ref('array')->exists()),
ref('id')->isEven()->or(ref('array')->exists()),
lit('found'),
lit('not found')
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Flow\ETL\Tests\Unit\Function;

use function Flow\ETL\DSL\{int_entry, lit, ref, row};
use Flow\ETL\Tests\FlowTestCase;

final class LogicalFunctionsTest extends FlowTestCase
{
public function test_logical_operations() : void
{
self::assertFalse(ref('id')->isEven()->andNot(ref('id')->equals(lit(1)))->eval(row(int_entry('id', 1))));
self::assertTrue(ref('id')->isOdd()->and(ref('id')->equals(lit(1)))->eval(row(int_entry('id', 1))));
self::assertTrue(ref('id')->isEven()->or(ref('id')->equals(lit(1)))->eval(row(int_entry('id', 1))));
self::assertFalse(ref('id')->isOdd()->andNot(ref('id')->equals(lit(1)))->eval(row(int_entry('id', 1))));
}
}

0 comments on commit 39f3d51

Please sign in to comment.