From e49fd0f8c081392c4d9f2171fbf8146c21c27ec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Tue, 26 Nov 2024 12:25:18 +0100 Subject: [PATCH] Fix Pagination when token is an array --- .../src/Generator/PaginationGenerator.php | 31 +++++++++++++++---- src/Service/DynamoDb/CHANGELOG.md | 4 +++ .../src/Result/BatchGetItemOutput.php | 2 +- .../DynamoDb/src/Result/QueryOutput.php | 2 +- .../DynamoDb/src/Result/ScanOutput.php | 2 +- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/CodeGenerator/src/Generator/PaginationGenerator.php b/src/CodeGenerator/src/Generator/PaginationGenerator.php index 90a63e5a1..9181b1633 100644 --- a/src/CodeGenerator/src/Generator/PaginationGenerator.php +++ b/src/CodeGenerator/src/Generator/PaginationGenerator.php @@ -5,8 +5,10 @@ namespace AsyncAws\CodeGenerator\Generator; use AsyncAws\CodeGenerator\Definition\ListShape; +use AsyncAws\CodeGenerator\Definition\MapShape; use AsyncAws\CodeGenerator\Definition\Operation; use AsyncAws\CodeGenerator\Definition\Pagination; +use AsyncAws\CodeGenerator\Definition\Shape; use AsyncAws\CodeGenerator\Definition\StructureShape; use AsyncAws\CodeGenerator\Generator\CodeGenerator\TypeGenerator; use AsyncAws\CodeGenerator\Generator\Naming\NamespaceRegistry; @@ -165,7 +167,7 @@ private function generateOutputPagination(Operation $operation, Pagination $pagi 'PROPERTY_NAME' => GeneratorHelper::normalizeName($resultKey), 'PAGE_LOADER_CODE' => $this->generateOutputPaginationLoader( strtr('yield from $page->PROPERTY_ACCESSOR;', ['PROPERTY_ACCESSOR' => GeneratorHelper::normalizeName($resultKey)]), - $common, $moreResult, $outputToken, $pagination, $classBuilder, $operation + $common, $moreResult, $outputToken, $pagination, $classBuilder, $operation, $shape ), ])); } @@ -182,7 +184,7 @@ private function generateOutputPagination(Operation $operation, Pagination $pagi 'PROPERTY_ACCESSOR' => 'get' . ucfirst(GeneratorHelper::normalizeName($resultKeys[0])), ]); } else { - $body = $this->generateOutputPaginationLoader($iteratorBody, $common, $moreResult, $outputToken, $pagination, $classBuilder, $operation); + $body = $this->generateOutputPaginationLoader($iteratorBody, $common, $moreResult, $outputToken, $pagination, $classBuilder, $operation, $shape); } $classBuilder->addMethod('getIterator') @@ -197,22 +199,39 @@ private function generateOutputPagination(Operation $operation, Pagination $pagi /** * @param string[] $outputToken */ - private function generateOutputPaginationLoader(string $iterator, string $common, string $moreResult, array $outputToken, Pagination $pagination, ClassBuilder $classBuilder, Operation $operation): string + private function generateOutputPaginationLoader(string $iterator, string $common, string $moreResult, array $outputToken, Pagination $pagination, ClassBuilder $classBuilder, Operation $operation, StructureShape $shape): string { if (empty($outputToken)) { return strtr($iterator, ['$page->' => '$this->']); } $inputToken = $pagination->getInputToken(); + $moreCondition = ''; + $moreShape = null; if (!$moreResult) { - $moreCondition = ''; foreach ($outputToken as $property) { - $moreCondition .= 'null !== ' . $this->generateGetter('$page', $property, (bool) $common); + $moreResult = $property; + $moreShape = $shape->getMember($moreResult)->getShape(); break; } } else { - $moreCondition = $this->generateGetter('$page', $moreResult, (bool) $common); + if ($common) { + $shape = $shape->getMember($common)->getShape(); + } + if ($shape instanceof StructureShape) { + $moreShape = $shape->getMember($moreResult)->getShape(); + } + } + + if ($moreResult) { + if ($moreShape instanceof ListShape || $moreShape instanceof MapShape) { + $moreCondition .= '[] !== ' . $this->generateGetter('$page', $moreResult, (bool) $common); + } elseif ($moreShape instanceof Shape && 'boolean' === $moreShape->getType()) { + $moreCondition .= $this->generateGetter('$page', $moreResult, (bool) $common); + } else { + $moreCondition .= 'null !== ' . $this->generateGetter('$page', $moreResult, (bool) $common); + } } $setter = ''; foreach ($inputToken as $index => $property) { diff --git a/src/Service/DynamoDb/CHANGELOG.md b/src/Service/DynamoDb/CHANGELOG.md index a370d4357..90248b28e 100644 --- a/src/Service/DynamoDb/CHANGELOG.md +++ b/src/Service/DynamoDb/CHANGELOG.md @@ -2,6 +2,10 @@ ## NOT RELEASED +### Changed + +- fix pagination when next token is an array + ## 3.3.0 ### Added diff --git a/src/Service/DynamoDb/src/Result/BatchGetItemOutput.php b/src/Service/DynamoDb/src/Result/BatchGetItemOutput.php index 11237a387..ed57f411a 100644 --- a/src/Service/DynamoDb/src/Result/BatchGetItemOutput.php +++ b/src/Service/DynamoDb/src/Result/BatchGetItemOutput.php @@ -83,7 +83,7 @@ public function getConsumedCapacity(bool $currentPageOnly = false): iterable $page = $this; while (true) { $page->initialize(); - if (null !== $page->unprocessedKeys) { + if ([] !== $page->unprocessedKeys) { $input->setRequestItems($page->unprocessedKeys); $this->registerPrefetch($nextPage = $client->batchGetItem($input)); diff --git a/src/Service/DynamoDb/src/Result/QueryOutput.php b/src/Service/DynamoDb/src/Result/QueryOutput.php index 449e03d67..0b0a0693a 100644 --- a/src/Service/DynamoDb/src/Result/QueryOutput.php +++ b/src/Service/DynamoDb/src/Result/QueryOutput.php @@ -116,7 +116,7 @@ public function getItems(bool $currentPageOnly = false): iterable $page = $this; while (true) { $page->initialize(); - if (null !== $page->lastEvaluatedKey) { + if ([] !== $page->lastEvaluatedKey) { $input->setExclusiveStartKey($page->lastEvaluatedKey); $this->registerPrefetch($nextPage = $client->query($input)); diff --git a/src/Service/DynamoDb/src/Result/ScanOutput.php b/src/Service/DynamoDb/src/Result/ScanOutput.php index 85d2ca3b4..90ce249a5 100644 --- a/src/Service/DynamoDb/src/Result/ScanOutput.php +++ b/src/Service/DynamoDb/src/Result/ScanOutput.php @@ -116,7 +116,7 @@ public function getItems(bool $currentPageOnly = false): iterable $page = $this; while (true) { $page->initialize(); - if (null !== $page->lastEvaluatedKey) { + if ([] !== $page->lastEvaluatedKey) { $input->setExclusiveStartKey($page->lastEvaluatedKey); $this->registerPrefetch($nextPage = $client->scan($input));