GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 75bdf9...8faa57 )
by joseph
83:56 queued 81:04
created

setExtractorOnUpdater()

Size

Total Lines 40
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 10
nc 1
nop 1
dl 0
loc 40
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A BulkEntitySaveAndUpdateTest.php$0 ➔ getTableName() 0 3 1
A BulkEntitySaveAndUpdateTest.php$0 ➔ extract() 0 6 1
A BulkEntitySaveAndUpdateTest.php$0 ➔ getEntityFqn() 0 3 1
A BulkEntitySaveAndUpdateTest.php$0 ➔ __construct() 0 3 1
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta\Tests\Large\Entity\Savers;
4
5
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\AbstractGenerator;
6
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\EntityInterface;
7
use EdmondsCommerce\DoctrineStaticMeta\Entity\Savers\BulkEntitySaver;
8
use EdmondsCommerce\DoctrineStaticMeta\Entity\Savers\BulkEntityUpdater;
9
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityDebugDumper;
10
use EdmondsCommerce\DoctrineStaticMeta\Schema\MysqliConnectionFactory;
11
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\AbstractLargeTest;
12
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\AbstractTest;
13
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\TestCodeGenerator;
14
15
/**
16
 * @covers \EdmondsCommerce\DoctrineStaticMeta\Entity\Savers\BulkEntityUpdater
17
 * @covers \EdmondsCommerce\DoctrineStaticMeta\Entity\Savers\BulkEntitySaver
18
 * @covers \EdmondsCommerce\DoctrineStaticMeta\Entity\Savers\AbstractBulkProcess
19
 * @large
20
 */
21
class BulkEntitySaveAndUpdateTest extends AbstractLargeTest
22
{
23
    public const WORK_DIR = AbstractTest::VAR_PATH . '/' . self::TEST_TYPE_LARGE . '/BulkEntitySaveAndUpdateTest';
24
25
    public const TEST_PROJECT_ROOT_NAMESPACE = 'BulkEntitySaveAndUpdate';
26
27
    public const TEST_ENTITIES_ROOT_NAMESPACE = self::TEST_PROJECT_ROOT_NAMESPACE . '\\' .
28
                                                AbstractGenerator::ENTITIES_FOLDER_NAME;
29
30
    private const INTEGER_ID_ENTITY = self::TEST_ENTITIES_ROOT_NAMESPACE . TestCodeGenerator::TEST_ENTITY_INTEGER_KEY;
31
32
    protected static $buildOnce = true;
33
    /**
34
     * @var BulkEntitySaver
35
     */
36
    private $saver;
37
    /**
38
     * @var BulkEntityUpdater
39
     */
40
    private $updater;
41
42
    public function setup(): void
43
    {
44
        parent::setUp();
45
        if (false === self::$built) {
46
            $this->getTestCodeGenerator()
47
                 ->copyTo(self::WORK_DIR, self::TEST_PROJECT_ROOT_NAMESPACE);
48
            self::$built = true;
49
        }
50
        $this->saver   = new BulkEntitySaver($this->getEntityManager());
51
        $this->updater = new BulkEntityUpdater($this->getEntityManager(), new MysqliConnectionFactory());
52
    }
53
54
55
    /**
56
     * @test
57
     */
58
    public function itCanBulkSaveArraysOfLargeDataEntities()
59
    {
60
        $this->createDatabase();
61
        $this->saver->setChunkSize(100);
62
        $generator = $this->getTestEntityGeneratorFactory()
63
                          ->createForEntityFqn(self::INTEGER_ID_ENTITY)
64
                          ->getGenerator($this->getEntityManager(), self::INTEGER_ID_ENTITY);
65
        $entities  = [];
66
        $numToSave = (int)ceil($this->getDataSize() / 2);
67
        for ($i = 0; $i < $numToSave; $i++) {
68
            $entities[] = $this->getNextEntity($generator);
69
        }
70
        $this->saver->addEntitiesToSave($entities);
71
        $this->saver->endBulkProcess();
72
        $numEntities = $this->getRepositoryFactory()->getRepository(self::INTEGER_ID_ENTITY)->count();
73
        self::assertSame($numToSave, $numEntities);
74
75
        return $numEntities;
76
    }
77
78
    /**
79
     * @return int
80
     * @SuppressWarnings(PHPMD.Superglobals)
81
     */
82
    private function getDataSize(): int
83
    {
84
        if ($this->isQuickTests()) {
85
            return 200;
86
        }
87
        if (isset($_SERVER['BulkEntitySaveAndUpdateTest_DataSize'])) {
88
            return (int)$_SERVER['BulkEntitySaveAndUpdateTest_DataSize'];
89
        }
90
91
        return 1000;
92
    }
93
94
    private function getNextEntity(\Generator $generator): EntityInterface
95
    {
96
        $generator->next();
97
98
        return $generator->current();
99
    }
100
101
    /**
102
     * @test
103
     * @depends itCanBulkSaveArraysOfLargeDataEntities
104
     *
105
     * @param int $previouslySavedCount
106
     *
107
     * @return int
108
     * @throws \Doctrine\ORM\Mapping\MappingException
109
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
110
     */
111
    public function itCanBulkSaveLargeDataEntities(int $previouslySavedCount): int
112
    {
113
        $numEntities = $this->getRepositoryFactory()->getRepository(self::INTEGER_ID_ENTITY)->count();
114
        self::assertSame($previouslySavedCount, $numEntities);
115
        $this->saver->setChunkSize(100);
116
117
        $generator = $this->getTestEntityGeneratorFactory()
118
                          ->createForEntityFqn(self::INTEGER_ID_ENTITY)
119
                          ->getGenerator($this->getEntityManager(), self::INTEGER_ID_ENTITY);
120
        $numToSave = (int)ceil($this->getDataSize() / 2);
121
        for ($i = 0; $i < $numToSave; $i++) {
122
            $this->saver->addEntityToSave($this->getNextEntity($generator));
123
        }
124
        $this->saver->endBulkProcess();
125
        $numEntities = $this->getRepositoryFactory()->getRepository(self::INTEGER_ID_ENTITY)->count();
126
        self::assertGreaterThanOrEqual($this->getDataSize(), $numEntities);
127
128
        return $numEntities;
129
    }
130
131
    /**
132
     * @test
133
     * @depends itCanBulkSaveLargeDataEntities
134
     *
135
     * @param int $previouslySavedCount
136
     *
137
     * @return array
138
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
139
     */
140
    public function itCanBulkUpdateAnArrayOfLargeDataEntities(int $previouslySavedCount): array
141
    {
142
        $this->updater->setChunkSize(100);
143
        $this->setExtractorOnUpdater(self::INTEGER_ID_ENTITY);
144
145
        $repository = $this->getRepositoryFactory()->getRepository(self::INTEGER_ID_ENTITY);
146
        $entities   = $repository->findAll();
147
        $integer    = 100;
148
        $text       = 'blah blah blah';
149
        $this->updater->prepareEntitiesForBulkUpdate($entities);
150
        foreach ($entities as $entity) {
151
            $entity->setInteger($integer);
152
            $entity->setText($text);
153
        }
154
        $this->updater->addEntitiesToSave($entities);
155
        $entities = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $entities is dead and can be removed.
Loading history...
156
        $this->updater->endBulkProcess();
157
        $numEntities = $repository->count();
158
        self::assertSame($previouslySavedCount, $numEntities);
159
        $reloaded = $repository->findAll();
160
        $dumper   = new EntityDebugDumper();
161
        foreach ($reloaded as $entity) {
162
            self::assertSame($integer, $entity->getInteger(), $dumper->dump($entity));
163
            self::assertSame($text, $entity->getText(), $dumper->dump($entity));
164
        }
165
166
        return $reloaded;
167
    }
168
169
    private function setExtractorOnUpdater(string $entityFqn): void
170
    {
171
        $this->updater->setExtractor(
172
            new class($entityFqn) implements BulkEntityUpdater\BulkEntityUpdateHelper
173
            {
174
                /**
175
                 * @var string
176
                 */
177
                private $entityFqn;
178
179
                public function __construct(string $entityFqn)
180
                {
181
                    $this->entityFqn = $entityFqn;
182
                }
183
184
                public function getTableName(): string
185
                {
186
                    return 'integer_id_key_entity';
187
                }
188
189
                public function getEntityFqn(): string
190
                {
191
                    return $this->entityFqn;
192
                }
193
194
                /**
195
                 * Extract entity into an array: [columnName=>value]
196
                 *
197
                 * First item in array has to be the primary key
198
                 *
199
                 * @param EntityInterface $entity
200
                 *
201
                 * @return array
202
                 */
203
                public function extract(EntityInterface $entity): array
204
                {
205
                    return [
206
                        'id'      => $entity->getId(),
207
                        'integer' => $entity->getInteger(),
0 ignored issues
show
Bug introduced by
The method getInteger() does not exist on EdmondsCommerce\Doctrine...erfaces\EntityInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

207
                        'integer' => $entity->/** @scrutinizer ignore-call */ getInteger(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
208
                        'text'    => $entity->getText(),
0 ignored issues
show
Bug introduced by
The method getText() does not exist on EdmondsCommerce\Doctrine...erfaces\EntityInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

208
                        'text'    => $entity->/** @scrutinizer ignore-call */ getText(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
209
                    ];
210
                }
211
            }
212
        );
213
    }
214
215
    /**
216
     * @test
217
     * @depends itCanBulkUpdateAnArrayOfLargeDataEntities
218
     *
219
     * @param array $entities
220
     *
221
     * @return array|null
222
     */
223
    public function itCanAcceptARatioOfNonUpdatedRows(array $entities)
224
    {
225
        $this->setExtractorOnUpdater(self::INTEGER_ID_ENTITY);
226
        $this->updater->startBulkProcess();
227
        $this->updater->setRequireAffectedRatio(0);
228
        $this->updater->addEntitiesToSave($entities);
229
        $this->updater->endBulkProcess();
230
        $expected = 0;
231
        $actual   = $this->updater->getTotalAffectedRows();
232
        self::assertSame($expected, $actual);
233
234
        return $entities;
235
    }
236
237
    /**
238
     * @test
239
     * @depends itCanAcceptARatioOfNonUpdatedRows
240
     *
241
     * @param array $entities
242
     *
243
     * @throws \Exception
244
     */
245
    public function itWillExceptIfNotEnoughRowsUpdated(array $entities)
246
    {
247
        $this->updater->prepareEntitiesForBulkUpdate($entities);
248
        $skipped = 0;
249
        foreach ($entities as $entity) {
250
            if ($skipped > 3) {
251
                $entity->setInteger(200);
252
                $skipped = 0;
253
            }
254
            $skipped++;
255
        }
256
257
        $this->expectException(\RuntimeException::class);
258
        $this->expectExceptionMessage('Affected rows count of ');
259
260
        try {
261
            $this->setExtractorOnUpdater(self::INTEGER_ID_ENTITY);
262
            $this->updater->startBulkProcess();
263
            $this->updater->setRequireAffectedRatio(0.5);
264
            $this->updater->addEntitiesToSave($entities);
265
            $this->updater->endBulkProcess();
266
        } catch (\Exception $e) {
267
            $this->updater->endBulkProcess();
268
            throw $e;
269
        }
270
    }
271
}
272