Skip to content

Commit 3a44d9f

Browse files
authored
Merge pull request #94 from keboola/adamvyborny-PST-2078-allow-invalid-legacy-pks
[PST-2078] Allow invalid PKs and force-fallback to legacy manifest in that case
2 parents 174723f + b19872b commit 3a44d9f

File tree

2 files changed

+166
-3
lines changed

2 files changed

+166
-3
lines changed

src/Manifest/ManifestManager/Options/OutTable/Serializer/LegacyManifestNormalizer.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ public function normalize($object, ?string $format = null, array $context = []):
2020
/** @var ManifestOptions $object */
2121
$this->normalizeBasicProperties($object, $data);
2222
$this->normalizeTableMetadata($object, $data);
23+
$this->normalizeSchema($object, $data);
2324
if ($object->getLegacyPrimaryKeys() !== null) {
24-
$data['primary_key'] = $object->getLegacyPrimaryKeys();
25-
} else {
26-
$this->normalizeSchema($object, $data);
25+
if (!isset($data['primary_key'])) {
26+
$data['primary_key'] = [];
27+
}
28+
$data['primary_key'] = array_unique(array_merge($data['primary_key'], $object->getLegacyPrimaryKeys()));
2729
}
2830

2931
return $data;

tests/Manifest/ManifestManagerTest.php

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

55
namespace Keboola\Component\Tests\Manifest;
66

7+
use Generator;
78
use Keboola\Component\Manifest\ManifestManager;
89
use Keboola\Component\Manifest\ManifestManager\Options\OptionsValidationException;
910
use Keboola\Component\Manifest\ManifestManager\Options\OutFileManifestOptions;
@@ -168,6 +169,166 @@ public function testManifestWithOnlyPrimaryKeysSpecified(): void
168169
);
169170
}
170171

172+
/**
173+
* @dataProvider legacyPrimaryKeysDataProvider
174+
*/
175+
public function testManifestObjectWithExtraPrimaryKeysSpecified(
176+
array $legacyPrimaryKeys,
177+
array $schema,
178+
array $expectedManifest,
179+
): void {
180+
$manifest = (new ManifestOptions())
181+
->setDestination('destination-table')
182+
->setLegacyPrimaryKeys($legacyPrimaryKeys)
183+
->setSchema($schema);
184+
185+
$this->assertEqualsCanonicalizing($expectedManifest, $manifest->toArray());
186+
187+
// Test that toArray(legacy: false) force fallbacks to the same result
188+
$this->assertEqualsCanonicalizing(
189+
$expectedManifest,
190+
$manifest->toArray(false),
191+
);
192+
}
193+
194+
public function legacyPrimaryKeysDataProvider(): Generator
195+
{
196+
yield 'two columns, three legacy primary keys merging with two non-legacy' => [
197+
['id', 'number', 'name'],
198+
[
199+
new ManifestOptionsSchema(
200+
'id',
201+
[],
202+
false,
203+
true,
204+
),
205+
new ManifestOptionsSchema(
206+
'number',
207+
['base' => ['type' => 'INTEGER', 'default' => '0']],
208+
false,
209+
true,
210+
),
211+
],
212+
[
213+
'destination' => 'destination-table',
214+
'columns' => ['id', 'number'],
215+
'primary_key' => ['id', 'number', 'name'],
216+
'column_metadata' => [
217+
'id' => [
218+
[
219+
'key' => 'KBC.datatype.nullable',
220+
'value' => false,
221+
],
222+
],
223+
'number' => [
224+
[
225+
'key' => 'KBC.datatype.nullable',
226+
'value' => false,
227+
],
228+
[
229+
'key' => 'KBC.datatype.basetype',
230+
'value' => 'INTEGER',
231+
],
232+
[
233+
'key' => 'KBC.datatype.default',
234+
'value' => '0',
235+
],
236+
],
237+
],
238+
],
239+
];
240+
241+
yield 'two columns, one legacy primary key, two non-legacy' => [
242+
['name'],
243+
[
244+
new ManifestOptionsSchema(
245+
'id',
246+
[],
247+
false,
248+
true,
249+
),
250+
new ManifestOptionsSchema(
251+
'number',
252+
['base' => ['type' => 'INTEGER', 'default' => '0']],
253+
false,
254+
true,
255+
),
256+
],
257+
[
258+
'destination' => 'destination-table',
259+
'columns' => ['id', 'number'],
260+
'primary_key' => ['id', 'number', 'name'],
261+
'column_metadata' => [
262+
'id' => [
263+
[
264+
'key' => 'KBC.datatype.nullable',
265+
'value' => false,
266+
],
267+
],
268+
'number' => [
269+
[
270+
'key' => 'KBC.datatype.nullable',
271+
'value' => false,
272+
],
273+
[
274+
'key' => 'KBC.datatype.basetype',
275+
'value' => 'INTEGER',
276+
],
277+
[
278+
'key' => 'KBC.datatype.default',
279+
'value' => '0',
280+
],
281+
],
282+
],
283+
],
284+
];
285+
286+
yield 'two columns, three legacy primary keys' => [
287+
['id', 'number', 'name'],
288+
[
289+
new ManifestOptionsSchema(
290+
'id',
291+
[],
292+
false,
293+
false,
294+
),
295+
new ManifestOptionsSchema(
296+
'number',
297+
['base' => ['type' => 'INTEGER', 'default' => '0']],
298+
false,
299+
false,
300+
),
301+
],
302+
[
303+
'destination' => 'destination-table',
304+
'columns' => ['id', 'number'],
305+
'primary_key' => ['id', 'number', 'name'],
306+
'column_metadata' => [
307+
'id' => [
308+
[
309+
'key' => 'KBC.datatype.nullable',
310+
'value' => false,
311+
],
312+
],
313+
'number' => [
314+
[
315+
'key' => 'KBC.datatype.nullable',
316+
'value' => false,
317+
],
318+
[
319+
'key' => 'KBC.datatype.basetype',
320+
'value' => 'INTEGER',
321+
],
322+
[
323+
'key' => 'KBC.datatype.default',
324+
'value' => '0',
325+
],
326+
],
327+
],
328+
],
329+
];
330+
}
331+
171332
public function testNonexistentManifestReturnsEmptyArray(): void
172333
{
173334
$manager = new ManifestManager(__DIR__ . '/fixtures/manifest-data-dir');

0 commit comments

Comments
 (0)