Skip to content

Commit 4011f39

Browse files
AUDULjeremycr
andauthored
V5 (#72)
* Added Symfony 7 support * Removed Symfony 6 compatibility * Removed Symfony 5 compatibility * Removed Symfony 4 compatibility * Removed Symfony 3 compatibility * Changed README.md * Added CI --------- Co-authored-by: Jérémy J <[email protected]>
1 parent db37c4b commit 4011f39

39 files changed

+295
-302
lines changed

.github/workflows/ci.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: CI
2+
3+
on: [push]
4+
5+
jobs:
6+
build-test:
7+
runs-on: ubuntu-latest
8+
9+
steps:
10+
- uses: actions/checkout@v4
11+
- uses: php-actions/composer@v6 # or alternative dependency management
12+
- uses: php-actions/phpunit@v4

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ composer.lock
33
.phpunit.result.cache
44
.php_cs.cache
55
.php_cs
6+
.idea
7+
.phpunit.cache
8+
.php-version

README.md

Lines changed: 59 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
# Code Rhapsodie Dataflow Bundle
22

3-
DataflowBundle is a bundle for Symfony 3.4+
3+
DataflowBundle is a bundle for Symfony 3.4+
44
providing an easy way to create import / export dataflow.
55

6+
| Dataflow | Symfony | Support |
7+
|----------|--------------------------|---------|
8+
| 5.x | 7.x | yes |
9+
| 4.x | 3.4 \| 4.x \| 5.x \| 6.x | yes |
10+
| 3.x | 3.4 \| 4.x \| 5.x | no |
11+
| 2.x | 3.4 \| 4.x | no |
12+
| 1.x | 3.4 \| 4.x | no |
13+
614
Dataflow uses a linear generic workflow in three parts:
7-
* one reader
8-
* any number of steps that can be synchronous or asynchronous
9-
* one or more writers
1015

11-
The reader can read data from anywhere and return data row by row. Each step processes the current row data.
16+
* one reader
17+
* any number of steps that can be synchronous or asynchronous
18+
* one or more writers
19+
20+
The reader can read data from anywhere and return data row by row. Each step processes the current row data.
1221
The steps are executed in the order in which they are added.
1322
And, one or more writers save the row anywhere you want.
1423

@@ -27,7 +36,6 @@ As the following schema shows, you can define more than one dataflow:
2736
* Display the result for the last Job for a Dataflow from the command line
2837
* Work with multiple Doctrine DBAL connections
2938

30-
3139
## Installation
3240

3341
Security notice: Symfony 4.x is not supported before 4.1.12, see https://github.com/advisories/GHSA-pgwj-prpq-jpc2
@@ -44,7 +52,8 @@ $ composer require code-rhapsodie/dataflow-bundle
4452

4553
You can use the generic readers, writers and steps from [PortPHP](https://github.com/portphp/portphp).
4654

47-
For the writers, you must use the adapter `CodeRhapsodie\DataflowBundle\DataflowType\Writer\PortWriterAdapter` like this:
55+
For the writers, you must use the adapter `CodeRhapsodie\DataflowBundle\DataflowType\Writer\PortWriterAdapter` like
56+
this:
4857

4958
```php
5059
<?php
@@ -57,9 +66,7 @@ $builder->addWriter(new \CodeRhapsodie\DataflowBundle\DataflowType\Writer\PortWr
5766

5867
### Register the bundle
5968

60-
#### Symfony 4 (new tree)
61-
62-
For Symfony 4, add `CodeRhapsodie\DataflowBundle\CodeRhapsodieDataflowBundle::class => ['all' => true],
69+
Add `CodeRhapsodie\DataflowBundle\CodeRhapsodieDataflowBundle::class => ['all' => true],
6370
` in the `config/bundles.php` file.
6471

6572
Like this:
@@ -74,32 +81,13 @@ return [
7481
];
7582
```
7683

77-
#### Symfony 3.4 (old tree)
78-
79-
For Symfony 3.4, add a new line in the `app/AppKernel.php` file.
80-
81-
Like this:
82-
83-
```php
84-
<?php
85-
// app/AppKernel.php
86-
87-
public function registerBundles()
88-
{
89-
$bundles = [
90-
// ...
91-
new CodeRhapsodie\DataflowBundle\CodeRhapsodieDataflowBundle(),
92-
// ...
93-
];
94-
}
95-
```
96-
9784
### Update the database
9885

9986
This bundle uses Doctrine DBAL to store Dataflow schedule into the database table (`cr_dataflow_scheduled`)
10087
and jobs (`cr_dataflow_job`).
10188

102-
If you use [Doctrine Migration Bundle](https://symfony.com/doc/master/bundles/DoctrineMigrationsBundle/index.html) or [Phinx](https://phinx.org/)
89+
If you use [Doctrine Migration Bundle](https://symfony.com/doc/master/bundles/DoctrineMigrationsBundle/index.html)
90+
or [Phinx](https://phinx.org/)
10391
or [Kaliop Migration Bundle](https://github.com/kaliop-uk/ezmigrationbundle) or whatever,
10492
you can add a new migration with the generated SQL query from this command:
10593

@@ -137,6 +125,7 @@ Dataflow can delegate the execution of its jobs to the Symfony messenger compone
137125
This allows jobs to be executed concurrently by workers instead of sequentially.
138126

139127
To enable messenger mode:
128+
140129
```yaml
141130
code_rhapsodie_dataflow:
142131
messenger_mode:
@@ -145,6 +134,7 @@ code_rhapsodie_dataflow:
145134
```
146135

147136
You also need to route Dataflow messages to the proper transport:
137+
148138
```yaml
149139
# config/packages/messenger.yaml
150140
framework:
@@ -158,9 +148,11 @@ framework:
158148

159149
## Define a dataflow type
160150

161-
This bundle uses a fixed and simple workflow structure in order to let you focus on the data processing logic part of your dataflow.
151+
This bundle uses a fixed and simple workflow structure in order to let you focus on the data processing logic part of
152+
your dataflow.
162153

163154
A dataflow type defines the different parts of your dataflow. A dataflow is made of:
155+
164156
- exactly one *Reader*
165157
- any number of *Steps*
166158
- one or more *Writers*
@@ -169,8 +161,10 @@ Dataflow types can be configured with options.
169161

170162
A dataflow type must implement `CodeRhapsodie\DataflowBundle\DataflowType\DataflowTypeInterface`.
171163

172-
To help with creating your dataflow types, an abstract class `CodeRhapsodie\DataflowBundle\DataflowType\AbstractDataflowType`
173-
is provided, allowing you to define your dataflow through a handy builder `CodeRhapsodie\DataflowBundle\DataflowType\DataflowBuilder`.
164+
To help with creating your dataflow types, an abstract
165+
class `CodeRhapsodie\DataflowBundle\DataflowType\AbstractDataflowType`
166+
is provided, allowing you to define your dataflow through a handy
167+
builder `CodeRhapsodie\DataflowBundle\DataflowType\DataflowBuilder`.
174168

175169
This is an example to define one class DataflowType:
176170

@@ -230,15 +224,16 @@ class MyFirstDataflowType extends AbstractDataflowType
230224

231225
Dataflow types must be tagged with `coderhapsodie.dataflow.type`.
232226

233-
If you're using Symfony auto-configuration for your services, this tag will be automatically added to all services implementing `DataflowTypeInterface`.
227+
If you're using Symfony auto-configuration for your services, this tag will be automatically added to all services
228+
implementing `DataflowTypeInterface`.
234229

235230
Otherwise, manually add the tag `coderhapsodie.dataflow.type` in your dataflow type service configuration:
236231

237232
```yaml
238233
```yaml
239-
CodeRhapsodie\DataflowExemple\DataflowType\MyFirstDataflowType:
240-
tags:
241-
- { name: coderhapsodie.dataflow.type }
234+
CodeRhapsodie\DataflowExemple\DataflowType\MyFirstDataflowType:
235+
tags:
236+
- { name: coderhapsodie.dataflow.type }
242237
```
243238
244239
### Use options for your dataflow type
@@ -264,11 +259,14 @@ class MyFirstDataflowType extends AbstractDataflowType
264259
}
265260
```
266261

267-
With this configuration, the option `fileName` is required. For an advanced usage of the option resolver, read the [Symfony documentation](https://symfony.com/doc/current/components/options_resolver.html).
262+
With this configuration, the option `fileName` is required. For an advanced usage of the option resolver, read
263+
the [Symfony documentation](https://symfony.com/doc/current/components/options_resolver.html).
268264

269265
For asynchronous management, `AbstractDataflowType` come with two default options :
266+
270267
- loopInterval : default to 0. Update this interval if you wish customise the `tick` loop duration.
271-
- emitInterval : default to 0. Update this interval to have a control when reader must emit new data in the flow pipeline.
268+
- emitInterval : default to 0. Update this interval to have a control when reader must emit new data in the flow
269+
pipeline.
272270

273271
### Logging
274272

@@ -292,14 +290,15 @@ class MyDataflowType extends AbstractDataflowType
292290
}
293291
```
294292

295-
When using the `code-rhapsodie:dataflow:run-pending` command, this logger will also be used to save the log in the corresponding job in the database.
293+
When using the `code-rhapsodie:dataflow:run-pending` command, this logger will also be used to save the log in the
294+
corresponding job in the database.
296295

297296
### Check if your DataflowType is ready
298297

299298
Execute this command to check if your DataflowType is correctly registered:
300299

301300
```shell script
302-
$ bin/console debug:container --tag coderhapsodie.dataflow.type --show-private
301+
$ bin/console debug:container --tag coderhapsodie.dataflow.type
303302
```
304303

305304
The result is like this:
@@ -316,10 +315,10 @@ Symfony Container Public and Private Services Tagged with "coderhapsodie.dataflo
316315
317316
```
318317

319-
320318
### Readers
321319

322-
*Readers* provide the dataflow with elements to import / export. Usually, elements are read from an external resource (file, database, webservice, etc).
320+
*Readers* provide the dataflow with elements to import / export. Usually, elements are read from an external resource (
321+
file, database, webservice, etc).
323322

324323
A *Reader* can be any `iterable`.
325324

@@ -357,15 +356,16 @@ You can set up this reader as follows:
357356
$builder->setReader(($this->myReader)())
358357
```
359358

360-
361359
### Steps
362360

363361
*Steps* are operations performed on the elements before they are handled by the *Writers*. Usually, steps are either:
362+
364363
- converters, that alter the element
365364
- filters, that conditionally prevent further operations on the element
366365
- generators, that can include asynchronous operations
367366

368367
A *Step* can be any callable, taking the element as its argument, and returning either:
368+
369369
- the element, possibly altered
370370
- `false`, if no further operations should be performed on this element
371371

@@ -409,7 +409,8 @@ Note : you can ensure writing order for asynchronous operations if all steps are
409409
*Writers* perform the actual import / export operations.
410410

411411
A *Writer* must implement `CodeRhapsodie\DataflowBundle\DataflowType\Writer\WriterInterface`.
412-
As this interface is not compatible with `Port\Writer`, the adapter `CodeRhapsodie\DataflowBundle\DataflowType\Writer\PortWriterAdapter` is provided.
412+
As this interface is not compatible with `Port\Writer`, the
413+
adapter `CodeRhapsodie\DataflowBundle\DataflowType\Writer\PortWriterAdapter` is provided.
413414

414415
This example show how to use the predefined PhpPort Writer :
415416

@@ -460,7 +461,9 @@ class FileWriter implements WriterInterface
460461

461462
#### CollectionWriter
462463

463-
If you want to write multiple items from a single item read, you can use the generic `CollectionWriter`. This writer will iterate over any `iterable` it receives, and pass each item from that collection to your own writer that handles single items.
464+
If you want to write multiple items from a single item read, you can use the generic `CollectionWriter`. This writer
465+
will iterate over any `iterable` it receives, and pass each item from that collection to your own writer that handles
466+
single items.
464467

465468
```php
466469
$builder->addWriter(new CollectionWriter($mySingleItemWriter));
@@ -470,9 +473,11 @@ $builder->addWriter(new CollectionWriter($mySingleItemWriter));
470473

471474
If you want to call different writers depending on what item is read, you can use the generic `DelegatorWriter`.
472475

473-
As an example, let's suppose our items are arrays with the first entry being either `product` or `order`. We want to use a different writer based on that value.
476+
As an example, let's suppose our items are arrays with the first entry being either `product` or `order`. We want to use
477+
a different writer based on that value.
474478

475-
First, create your writers implementing `DelegateWriterInterface` (this interface extends `WriterInterface` so your writers can still be used without the `DelegatorWriter`).
479+
First, create your writers implementing `DelegateWriterInterface` (this interface extends `WriterInterface` so your
480+
writers can still be used without the `DelegatorWriter`).
476481

477482
```php
478483
<?php
@@ -545,7 +550,8 @@ Then, configure your `DelegatorWriter` and add it to your dataflow type.
545550
}
546551
```
547552

548-
During execution, the `DelegatorWriter` will simply pass each item received to its first delegate (in the order those were added) that supports it. If no delegate supports an item, an exception will be thrown.
553+
During execution, the `DelegatorWriter` will simply pass each item received to its first delegate (in the order those
554+
were added) that supports it. If no delegate supports an item, an exception will be thrown.
549555

550556
## Queue
551557

@@ -563,7 +569,8 @@ Several commands are provided to manage schedules and run jobs.
563569

564570
`code-rhapsodie:dataflow:run-pending` Executes job in the queue according to their schedule.
565571

566-
When messenger mode is enabled, jobs will still be created according to their schedule, but execution will be handled by the messenger component instead.
572+
When messenger mode is enabled, jobs will still be created according to their schedule, but execution will be handled by
573+
the messenger component instead.
567574

568575
`code-rhapsodie:dataflow:schedule:list` Display the list of dataflows scheduled.
569576

@@ -602,7 +609,7 @@ $ bin/console code-rhapsodie:dataflow:run-pending --connection=default
602609

603610
Please report issues and request features at https://github.com/code-rhapsodie/dataflow-bundle/issues.
604611

605-
Please note that only the last release of the 3.x and the 4.x versions of this bundle are actively supported.
612+
Please note that only the last release of the 4.x and the 5.x versions of this bundle are actively supported.
606613

607614
# Contributing
608615

Tests/DataflowType/Dataflow/AMPAsyncDataflowTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use Amp\Delayed;
66
use CodeRhapsodie\DataflowBundle\DataflowType\Dataflow\AMPAsyncDataflow;
7-
use CodeRhapsodie\DataflowBundle\DataflowType\Dataflow\Dataflow;
87
use CodeRhapsodie\DataflowBundle\DataflowType\Writer\WriterInterface;
98
use PHPUnit\Framework\TestCase;
109

Tests/DataflowType/Writer/CollectionWriterTest.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,13 @@ public function testAll()
4040
->expects($this->once())
4141
->method('finish')
4242
;
43+
$matcher = $this->exactly(count($values));
4344
$embeddedWriter
44-
->expects($this->exactly(count($values)))
45+
->expects($matcher)
4546
->method('write')
46-
->withConsecutive(...array_map(fn($item) => [$item], $values))
47+
->with($this->callback(function ($arg) use ($matcher, $values) {
48+
return $arg === $values[$matcher->numberOfInvocations() - 1];
49+
}))
4750
;
4851

4952
$writer = new CollectionWriter($embeddedWriter);

Tests/DataflowType/Writer/DelegatorWriterTest.php

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,10 @@
1010

1111
class DelegatorWriterTest extends TestCase
1212
{
13-
private \CodeRhapsodie\DataflowBundle\DataflowType\Writer\DelegatorWriter $delegatorWriter;
14-
15-
private \CodeRhapsodie\DataflowBundle\DataflowType\Writer\DelegateWriterInterface|\PHPUnit\Framework\MockObject\MockObject $delegateInt;
16-
17-
private \CodeRhapsodie\DataflowBundle\DataflowType\Writer\DelegateWriterInterface|\PHPUnit\Framework\MockObject\MockObject $delegateString;
18-
19-
private \CodeRhapsodie\DataflowBundle\DataflowType\Writer\DelegateWriterInterface|\PHPUnit\Framework\MockObject\MockObject $delegateArray;
13+
private DelegatorWriter $delegatorWriter;
14+
private DelegateWriterInterface|MockObject $delegateInt;
15+
private DelegateWriterInterface|MockObject $delegateString;
16+
private DelegateWriterInterface|MockObject $delegateArray;
2017

2118
protected function setUp(): void
2219
{

Tests/DataflowType/Writer/PortWriterAdapterTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public function testAll()
1212
$value = 'not an array';
1313

1414
$writer = $this->getMockBuilder('\Port\Writer')
15-
->setMethods(['prepare', 'finish', 'writeItem'])
15+
->onlyMethods(['prepare', 'finish', 'writeItem'])
1616
->getMock()
1717
;
1818
$writer

0 commit comments

Comments
 (0)