From 0e70287b08931ab9c1ba8f6c68bec29d3b0a331d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=BDborn=C3=BD=20Adam?= Date: Thu, 26 Sep 2024 18:17:34 +0200 Subject: [PATCH 1/2] feat: allow invalid PKs and force-fallback to legacy manifest in that case --- .../OutTable/Serializer/LegacyManifestNormalizer.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Manifest/ManifestManager/Options/OutTable/Serializer/LegacyManifestNormalizer.php b/src/Manifest/ManifestManager/Options/OutTable/Serializer/LegacyManifestNormalizer.php index 74816bf..a2722de 100644 --- a/src/Manifest/ManifestManager/Options/OutTable/Serializer/LegacyManifestNormalizer.php +++ b/src/Manifest/ManifestManager/Options/OutTable/Serializer/LegacyManifestNormalizer.php @@ -20,10 +20,12 @@ public function normalize($object, ?string $format = null, array $context = []): /** @var ManifestOptions $object */ $this->normalizeBasicProperties($object, $data); $this->normalizeTableMetadata($object, $data); + $this->normalizeSchema($object, $data); if ($object->getLegacyPrimaryKeys() !== null) { - $data['primary_key'] = $object->getLegacyPrimaryKeys(); - } else { - $this->normalizeSchema($object, $data); + if (!isset($data['primary_key'])) { + $data['primary_key'] = []; + } + $data['primary_key'] = array_unique(array_merge($data['primary_key'], $object->getLegacyPrimaryKeys())); } return $data; From b19872b65c8b32452e4bebcc7423e3c61663cd49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=BDborn=C3=BD=20Adam?= Date: Thu, 26 Sep 2024 18:18:10 +0200 Subject: [PATCH 2/2] test: testing legacy primary keys with non-existing columns --- tests/Manifest/ManifestManagerTest.php | 161 +++++++++++++++++++++++++ 1 file changed, 161 insertions(+) diff --git a/tests/Manifest/ManifestManagerTest.php b/tests/Manifest/ManifestManagerTest.php index 7349d89..0d821ff 100644 --- a/tests/Manifest/ManifestManagerTest.php +++ b/tests/Manifest/ManifestManagerTest.php @@ -4,6 +4,7 @@ namespace Keboola\Component\Tests\Manifest; +use Generator; use Keboola\Component\Manifest\ManifestManager; use Keboola\Component\Manifest\ManifestManager\Options\OptionsValidationException; use Keboola\Component\Manifest\ManifestManager\Options\OutFileManifestOptions; @@ -168,6 +169,166 @@ public function testManifestWithOnlyPrimaryKeysSpecified(): void ); } + /** + * @dataProvider legacyPrimaryKeysDataProvider + */ + public function testManifestObjectWithExtraPrimaryKeysSpecified( + array $legacyPrimaryKeys, + array $schema, + array $expectedManifest, + ): void { + $manifest = (new ManifestOptions()) + ->setDestination('destination-table') + ->setLegacyPrimaryKeys($legacyPrimaryKeys) + ->setSchema($schema); + + $this->assertEqualsCanonicalizing($expectedManifest, $manifest->toArray()); + + // Test that toArray(legacy: false) force fallbacks to the same result + $this->assertEqualsCanonicalizing( + $expectedManifest, + $manifest->toArray(false), + ); + } + + public function legacyPrimaryKeysDataProvider(): Generator + { + yield 'two columns, three legacy primary keys merging with two non-legacy' => [ + ['id', 'number', 'name'], + [ + new ManifestOptionsSchema( + 'id', + [], + false, + true, + ), + new ManifestOptionsSchema( + 'number', + ['base' => ['type' => 'INTEGER', 'default' => '0']], + false, + true, + ), + ], + [ + 'destination' => 'destination-table', + 'columns' => ['id', 'number'], + 'primary_key' => ['id', 'number', 'name'], + 'column_metadata' => [ + 'id' => [ + [ + 'key' => 'KBC.datatype.nullable', + 'value' => false, + ], + ], + 'number' => [ + [ + 'key' => 'KBC.datatype.nullable', + 'value' => false, + ], + [ + 'key' => 'KBC.datatype.basetype', + 'value' => 'INTEGER', + ], + [ + 'key' => 'KBC.datatype.default', + 'value' => '0', + ], + ], + ], + ], + ]; + + yield 'two columns, one legacy primary key, two non-legacy' => [ + ['name'], + [ + new ManifestOptionsSchema( + 'id', + [], + false, + true, + ), + new ManifestOptionsSchema( + 'number', + ['base' => ['type' => 'INTEGER', 'default' => '0']], + false, + true, + ), + ], + [ + 'destination' => 'destination-table', + 'columns' => ['id', 'number'], + 'primary_key' => ['id', 'number', 'name'], + 'column_metadata' => [ + 'id' => [ + [ + 'key' => 'KBC.datatype.nullable', + 'value' => false, + ], + ], + 'number' => [ + [ + 'key' => 'KBC.datatype.nullable', + 'value' => false, + ], + [ + 'key' => 'KBC.datatype.basetype', + 'value' => 'INTEGER', + ], + [ + 'key' => 'KBC.datatype.default', + 'value' => '0', + ], + ], + ], + ], + ]; + + yield 'two columns, three legacy primary keys' => [ + ['id', 'number', 'name'], + [ + new ManifestOptionsSchema( + 'id', + [], + false, + false, + ), + new ManifestOptionsSchema( + 'number', + ['base' => ['type' => 'INTEGER', 'default' => '0']], + false, + false, + ), + ], + [ + 'destination' => 'destination-table', + 'columns' => ['id', 'number'], + 'primary_key' => ['id', 'number', 'name'], + 'column_metadata' => [ + 'id' => [ + [ + 'key' => 'KBC.datatype.nullable', + 'value' => false, + ], + ], + 'number' => [ + [ + 'key' => 'KBC.datatype.nullable', + 'value' => false, + ], + [ + 'key' => 'KBC.datatype.basetype', + 'value' => 'INTEGER', + ], + [ + 'key' => 'KBC.datatype.default', + 'value' => '0', + ], + ], + ], + ], + ]; + } + public function testNonexistentManifestReturnsEmptyArray(): void { $manager = new ManifestManager(__DIR__ . '/fixtures/manifest-data-dir');