Skip to content

Commit 45b0799

Browse files
authored
Add an item writer that will only write items satisfying a condition (#62)
* Add an item writer that will only write items that are satisfying a condition * Add ConditionalWriter in main doc
1 parent 9976efb commit 45b0799

File tree

3 files changed

+122
-0
lines changed

3 files changed

+122
-0
lines changed

src/batch/docs/domain/item-job/item-writer.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ It can be any class implementing [ItemWriterInterface](../../../src/Job/Item/Ite
1111
write items as a json string each on a line of a file.
1212
- [ChainWriter](../../../src/Job/Item/Writer/ChainWriter.php):
1313
write items on multiple item writers.
14+
- [ConditionalWriter](../../../src/Job/Item/Writer/ConditionalWriter.php):
15+
will only write items that are matching your conditions.
1416
- [NullWriter](../../../src/Job/Item/Writer/NullWriter.php):
1517
do not write items.
1618
- [RoutingWriter](../../../src/Job/Item/Writer/RoutingWriter.php):
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yokai\Batch\Job\Item\Writer;
6+
7+
use Yokai\Batch\Job\Item\ElementConfiguratorTrait;
8+
use Yokai\Batch\Job\Item\FlushableInterface;
9+
use Yokai\Batch\Job\Item\InitializableInterface;
10+
use Yokai\Batch\Job\Item\ItemWriterInterface;
11+
use Closure;
12+
use Yokai\Batch\Job\JobExecutionAwareInterface;
13+
use Yokai\Batch\Job\JobExecutionAwareTrait;
14+
15+
/**
16+
* This {@see ItemWriterInterface} will transfer writing
17+
* to another {@see ItemWriterInterface},
18+
* if the closure you provided tells to.
19+
*/
20+
final class ConditionalWriter implements
21+
ItemWriterInterface,
22+
JobExecutionAwareInterface,
23+
InitializableInterface,
24+
FlushableInterface
25+
{
26+
use JobExecutionAwareTrait;
27+
use ElementConfiguratorTrait;
28+
29+
private bool $initialized = false;
30+
31+
public function __construct(
32+
private Closure $shouldWrite,
33+
private ItemWriterInterface $writer,
34+
) {
35+
}
36+
37+
public function write(iterable $items): void
38+
{
39+
$keptItems = [];
40+
foreach ($items as $item) {
41+
if (($this->shouldWrite)($item, $this->jobExecution)) {
42+
$keptItems[] = $item;
43+
}
44+
}
45+
46+
if ($keptItems === []) {
47+
return;
48+
}
49+
50+
if (!$this->initialized) {
51+
$this->configureElementJobContext($this->writer, $this->jobExecution);
52+
$this->initializeElement($this->writer);
53+
$this->initialized = true;
54+
}
55+
56+
$this->writer->write($keptItems);
57+
}
58+
59+
public function initialize(): void
60+
{
61+
$this->initialized = false;
62+
}
63+
64+
public function flush(): void
65+
{
66+
if ($this->initialized) {
67+
$this->flushElement($this->writer);
68+
}
69+
}
70+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yokai\Batch\Tests\Job\Item\Writer;
6+
7+
use Yokai\Batch\Job\Item\Writer\ConditionalWriter;
8+
use PHPUnit\Framework\TestCase;
9+
use Yokai\Batch\JobExecution;
10+
use Yokai\Batch\Test\Job\Item\Writer\InMemoryWriter;
11+
use Yokai\Batch\Test\Job\Item\Writer\TestDebugWriter;
12+
13+
class ConditionalWriterTest extends TestCase
14+
{
15+
public function testWriteSomething(): void
16+
{
17+
$writer = new ConditionalWriter(
18+
fn (int $number) => ($number % 2) === 0,
19+
$debugWriter = new TestDebugWriter($memoryWriter = new InMemoryWriter())
20+
);
21+
22+
$writer->setJobExecution(JobExecution::createRoot('123', 'test.conditional_writer'));
23+
$writer->initialize();
24+
$writer->write([1, 2, 3, 4, 5]);
25+
$writer->write([6, 7, 8]);
26+
$writer->flush();
27+
28+
$debugWriter->assertWasConfigured();
29+
$debugWriter->assertWasUsed();
30+
self::assertSame([[2, 4], [6, 8]], $memoryWriter->getBatchItems());
31+
}
32+
33+
public function testWriteNothing(): void
34+
{
35+
$writer = new ConditionalWriter(
36+
fn () => false,
37+
$debugWriter = new TestDebugWriter($memoryWriter = new InMemoryWriter())
38+
);
39+
40+
$writer->setJobExecution(JobExecution::createRoot('123', 'test.conditional_writer'));
41+
$writer->initialize();
42+
$writer->write([1, 2, 3, 4, 5]);
43+
$writer->write([6, 7, 8]);
44+
$writer->flush();
45+
46+
$debugWriter->assertWasNotConfigured();
47+
$debugWriter->assertWasNotUsed();
48+
self::assertSame([], $memoryWriter->getBatchItems());
49+
}
50+
}

0 commit comments

Comments
 (0)