Skip to content

Commit

Permalink
Feat: Transformers can now return single values for a better DX (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
bpolaszek authored Nov 3, 2023
1 parent 4ccf009 commit 537a906
Show file tree
Hide file tree
Showing 7 changed files with 16 additions and 22 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ Now let's have a look on how simple it is:
use Bentools\ETL\EtlExecutor;

$etl = (new EtlExecutor())
->transformWith(function (string $name) {
yield strtoupper($name);
});
->transformWith(fn (string $name) => strtoupper($name));

$singers = ['Bob Marley', 'Amy Winehouse'];
$report = $etl->process($singers);
Expand Down Expand Up @@ -128,7 +126,9 @@ $etl = (new EtlExecutor())
$etl->process('file:///tmp/cities.csv', $pdo);
```

As you can see, you can use `EtlState.destination` to retrieve the second argument you passed yo `$etl->process()`.
As you can see:
- Your transformer can _yield_ values, in case 1 extracted item becomes several items to load
- You can use `EtlState.destination` to retrieve the second argument you passed yo `$etl->process()`.

The `EtlState` object contains all elements relative to the state of your ETL workflow being running.

Expand Down
3 changes: 2 additions & 1 deletion src/EtlExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ private function extract(EtlState &$state): Generator
private function transform(mixed $item, EtlState $state): array
{
try {
$items = [...$this->transformer->transform($item, $state)];
$transformed = $this->transformer->transform($item, $state);
$items = $transformed instanceof Generator ? [...$transformed] : [$transformed];

return $this->dispatch(new TransformEvent($state, $items))->items;
} catch (SkipRequest|StopRequest $e) {
Expand Down
6 changes: 1 addition & 5 deletions src/Transformer/CallableTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use Bentools\ETL\EtlState;
use Closure;
use Generator;

final readonly class CallableTransformer implements TransformerInterface
{
Expand All @@ -15,10 +14,7 @@ public function __construct(
) {
}

/**
* @return Generator<mixed>
*/
public function transform(mixed $item, EtlState $state): Generator
public function transform(mixed $item, EtlState $state): mixed
{
return ($this->closure)($item, $state);
}
Expand Down
5 changes: 2 additions & 3 deletions src/Transformer/NullTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
namespace Bentools\ETL\Transformer;

use Bentools\ETL\EtlState;
use Generator;

final readonly class NullTransformer implements TransformerInterface
{
public function transform(mixed $item, EtlState $state): Generator
public function transform(mixed $item, EtlState $state): mixed
{
yield $item;
return $item;
}
}
6 changes: 1 addition & 5 deletions src/Transformer/TransformerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,8 @@
namespace Bentools\ETL\Transformer;

use Bentools\ETL\EtlState;
use Generator;

interface TransformerInterface
{
/**
* @return Generator<mixed>
*/
public function transform(mixed $item, EtlState $state): Generator;
public function transform(mixed $item, EtlState $state): mixed;
}
7 changes: 5 additions & 2 deletions tests/Unit/EtlExecutorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
use function expect;
use function strtoupper;

it('basically works', function () {
it('basically works', function (callable $transformer) {
$items = [];

// Given
$etl = (new EtlExecutor())
->extractFrom(fn () => yield from ['foo', 'bar'])
->transformWith(fn (mixed $value) => yield strtoupper($value))
->transformWith($transformer)
->loadInto(function (string $item) use (&$items) {
$items[] = $item;
})
Expand All @@ -31,4 +31,7 @@
->and($report->nbLoadedItems)->toBe(2)
->and($report->getDuration())->toBeBetween(0, 1)
;
})->with(function () {
yield 'Return value' => fn (mixed $value) => strtoupper($value);
yield 'Generator' => fn (mixed $value) => yield strtoupper($value);
});
3 changes: 1 addition & 2 deletions tests/Unit/Transformer/NullTransformerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use Bentools\ETL\Transformer\NullTransformer;

use function expect;
use function iterator_to_array;

it('yields the value as-is', function () {
// Given
Expand All @@ -19,5 +18,5 @@
$transformedItems = $transformer->transform('foo', $state);

// Then
expect(iterator_to_array($transformedItems))->toBe(['foo']);
expect($transformedItems)->toBe('foo');
});

0 comments on commit 537a906

Please sign in to comment.