lPipeMultilevelTest.php$0   A
last analyzed

Complexity

Total Complexity 1

Size/Duplication

Total Lines 7
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
wmc 1
lcom 0
cbo 0
1
<?php
2
declare(strict_types=1);
3
4
namespace SlayerBirden\DataFlow\Test\Functional;
5
6
use Doctrine\DBAL\Connection;
7
use Doctrine\DBAL\Driver\PDOConnection;
8
use Doctrine\DBAL\DriverManager;
9
use Doctrine\DBAL\Schema\Schema;
10
use PHPUnit\DbUnit\DataSet\IDataSet;
11
use PHPUnit\DbUnit\Operation\Factory;
12
use PHPUnit\DbUnit\TestCase;
13
use SlayerBirden\DataFlow\DataBagInterface;
14
use SlayerBirden\DataFlow\Emitter\BlackHole;
15
use SlayerBirden\DataFlow\PipelineBuilder;
16
use SlayerBirden\DataFlow\Plumber;
17
use SlayerBirden\DataFlow\Provider\ArrayProvider;
18
use SlayerBirden\DataFlow\Test\Functional\Exception\ConnectionException;
19
use SlayerBirden\DataFlow\Writer\Dbal\AutoIncrementCallbackInterface;
20
use SlayerBirden\DataFlow\Writer\Dbal\UpdateStrategy\UniqueIndexStrategy;
21
use SlayerBirden\DataFlow\Writer\Dbal\Write;
22
use SlayerBirden\DataFlow\Writer\Dbal\WriterUtility;
23
24
class DbalPipeMultilevelTest extends TestCase
25
{
26
    /**
27
     * @var Connection
28
     */
29
    private $connection;
30
    private $pipeline;
31
    private $emitter;
32
33
    protected function setUp(): void
34
    {
35
        $params = require __DIR__ . '/config/db-config.php';
36
        $this->connection = DriverManager::getConnection($params);
37
38
        $schema = new Schema();
39
40
        // create teams Table
41
        $table = $schema->createTable('teams');
42
        $table->addColumn('id', 'integer', [
43
            'autoincrement' => true,
44
        ]);
45
        $table->addColumn('name', 'string');
46
        $table->setPrimaryKey(['id']);
47
        $table->addUniqueIndex(['name']);
48
49
        // create heroes Table
50
        $table = $schema->createTable('heroes');
51
        $table->addColumn('id', 'integer', [
52
            'autoincrement' => true,
53
        ]);
54
        $table->addColumn('name', 'string');
55
        $table->addColumn('code', 'string');
56
        $table->addColumn('team_id', 'integer');
57
        $table->addForeignKeyConstraint('teams', ['team_id'], ['id']);
58
        $table->setPrimaryKey(['id']);
59
        $table->addUniqueIndex(['code']);
60
61
        $currentSchema = $this->connection->getSchemaManager()->createSchema();
62
        $sql = $currentSchema->getMigrateToSql($schema, $this->connection->getDatabasePlatform());
63
        array_walk($sql, function ($script) {
64
            $this->connection->executeUpdate($script);
65
        });
66
67
        parent::setUp();
68
        $this->emitter = new BlackHole();
69
        $utility = new WriterUtility($this->connection);
70
        $this->pipeline = (new PipelineBuilder($this->emitter))
71
            ->cp('name', 'hero_name') // copy to tmp hero_name
72
            ->cp('team', 'name') // copy team to name
73
            ->addSection(new Write(
74
                'teams_write',
75
                $this->connection,
76
                'teams',
77
                $utility,
78
                new UniqueIndexStrategy('teams', $utility),
79
                $this->emitter,
80
                new class implements AutoIncrementCallbackInterface
81
                {
82
                    public function __invoke(int $id, DataBagInterface $dataBag)
83
                    {
84
                        $dataBag['team_id'] = $id;
85
                    }
86
                }
87
            ))
88
            ->cp('hero_name', 'name') // copy hero_name back to name
89
            ->delete(['hero_name', 'team'])
90
            ->addSection(new Write(
91
                'heroes_write',
92
                $this->connection,
93
                'heroes',
94
                $utility,
95
                new UniqueIndexStrategy('heroes', $utility),
96
                $this->emitter
97
            ))
98
            ->build();
99
    }
100
101
    protected function getTearDownOperation()
102
    {
103
        return Factory::TRUNCATE();
104
    }
105
106
    /**
107
     * Returns the test database connection.
108
     *
109
     * @return \PHPUnit\DbUnit\Database\Connection
110
     */
111
    protected function getConnection()
112
    {
113
        $con = $this->connection->getWrappedConnection();
114
        if ($con instanceof PDOConnection) {
115
            return $this->createDefaultDBConnection($con);
116
        }
117
118
        throw new ConnectionException('Could not get PDO object.');
119
    }
120
121
    /**
122
     * Returns the test dataset.
123
     *
124
     * @return IDataSet
125
     */
126
    protected function getDataSet()
127
    {
128
        return $this->createArrayDataSet([
129
            'heroes' => [],
130
            'teams' => [],
131
        ]);
132
    }
133
134
    public function testDbMultiLevelPipeFlow()
135
    {
136
        $provider = new ArrayProvider('heroes', [
137
            [
138
                'name' => 'Spiderman',
139
                'code' => 'spider-man',
140
                'team' => 'Avengers',
141
            ],
142
            [
143
                'name' => 'Hulk',
144
                'code' => 'hulk',
145
                'team' => 'Avengers',
146
            ],
147
            [
148
                'name' => 'Super Man',
149
                'code' => 'superman',
150
                'team' => 'Justice League',
151
            ],
152
        ]);
153
        (new Plumber($provider, $this->pipeline, $this->emitter))->pour();
154
155
        $actualHeroes = $this->getConnection()->createQueryTable('heroes', 'SELECT * FROM `heroes`');
156
        $actualTeams = $this->getConnection()->createQueryTable('teams', 'SELECT * FROM `teams`');
157
        $expected = $this->createArrayDataSet([
158
            'heroes' => [
159
                [
160
                    'id' => 1,
161
                    'name' => 'Spiderman',
162
                    'code' => 'spider-man',
163
                    'team_id' => 1,
164
                ],
165
                [
166
                    'id' => 2,
167
                    'name' => 'Hulk',
168
                    'code' => 'hulk',
169
                    'team_id' => 1,
170
                ],
171
                [
172
                    'id' => 3,
173
                    'name' => 'Super Man',
174
                    'code' => 'superman',
175
                    'team_id' => 2,
176
                ],
177
            ],
178
            'teams' => [
179
                [
180
                    'id' => 1,
181
                    'name' => 'Avengers',
182
                ],
183
                [
184
                    'id' => 2,
185
                    'name' => 'Justice League',
186
                ],
187
            ],
188
        ]);
189
190
        $this->assertTablesEqual($expected->getTable('teams'), $actualTeams);
191
        $this->assertTablesEqual($expected->getTable('heroes'), $actualHeroes);
192
    }
193
}
194