From a6ff1d20562e1c9612a6fa6f910d54d0585b0552 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 23 Jan 2022 08:44:25 +0100 Subject: [PATCH] introduce Parameter object --- src/QueryReflection/Parameter.php | 47 +++++++++++++++++++ src/QueryReflection/PlaceholderValidation.php | 4 +- src/QueryReflection/QueryReflection.php | 40 ++++++++++++---- 3 files changed, 79 insertions(+), 12 deletions(-) create mode 100644 src/QueryReflection/Parameter.php diff --git a/src/QueryReflection/Parameter.php b/src/QueryReflection/Parameter.php new file mode 100644 index 000000000..965380e43 --- /dev/null +++ b/src/QueryReflection/Parameter.php @@ -0,0 +1,47 @@ +type = $type; + $this->simulatedValue = $simulatedValue; + $this->isOptional = $isOptional; + + if (null === $name) { + return; + } + + if (!str_starts_with($name, ':')) { + $name = ':'.$name; + } + + $this->name = $name; + } +} diff --git a/src/QueryReflection/PlaceholderValidation.php b/src/QueryReflection/PlaceholderValidation.php index aebfab0a3..144b93e1a 100644 --- a/src/QueryReflection/PlaceholderValidation.php +++ b/src/QueryReflection/PlaceholderValidation.php @@ -7,7 +7,7 @@ final class PlaceholderValidation { /** - * @param array $parameters + * @param array $parameters * * @return iterable */ @@ -39,7 +39,7 @@ public function checkErrors(string $queryString, array $parameters): iterable } /** - * @param array $parameters + * @param array $parameters * * @return iterable */ diff --git a/src/QueryReflection/QueryReflection.php b/src/QueryReflection/QueryReflection.php index ae73972d2..c52ad6b91 100644 --- a/src/QueryReflection/QueryReflection.php +++ b/src/QueryReflection/QueryReflection.php @@ -7,6 +7,7 @@ use PhpParser\Node\Expr; use PhpParser\Node\Expr\BinaryOp\Concat; use PHPStan\Analyser\Scope; +use PHPStan\ShouldNotHappenException; use PHPStan\Type\Constant\ConstantArrayType; use PHPStan\Type\Constant\ConstantIntegerType; use PHPStan\Type\Constant\ConstantStringType; @@ -204,7 +205,7 @@ public static function getQueryType(string $query): ?string * * @throws UnresolvableQueryException * - * @return array|null + * @return array|null */ public function resolveParameters(Type $parameterTypes): ?array { @@ -213,18 +214,35 @@ public function resolveParameters(Type $parameterTypes): ?array if ($parameterTypes instanceof ConstantArrayType) { $keyTypes = $parameterTypes->getKeyTypes(); $valueTypes = $parameterTypes->getValueTypes(); + $optionalKeys = $parameterTypes->getOptionalKeys(); foreach ($keyTypes as $i => $keyType) { + $isOptional = \in_array($i, $optionalKeys, true); + if ($keyType instanceof ConstantStringType) { $placeholderName = $keyType->getValue(); - if (!str_starts_with($placeholderName, ':')) { - $placeholderName = ':'.$placeholderName; + if ('' === $placeholderName) { + throw new ShouldNotHappenException('Empty placeholder name'); } - $parameters[$placeholderName] = QuerySimulation::simulateParamValueType($valueTypes[$i], true); + $param = new Parameter( + $placeholderName, + $valueTypes[$i], + QuerySimulation::simulateParamValueType($valueTypes[$i], true), + $isOptional + ); + + $parameters[$param->name] = $param; } elseif ($keyType instanceof ConstantIntegerType) { - $parameters[$keyType->getValue()] = QuerySimulation::simulateParamValueType($valueTypes[$i], true); + $param = new Parameter( + null, + $valueTypes[$i], + QuerySimulation::simulateParamValueType($valueTypes[$i], true), + $isOptional + ); + + $parameters[$keyType->getValue()] = $param; } } @@ -235,7 +253,7 @@ public function resolveParameters(Type $parameterTypes): ?array } /** - * @param array $parameters + * @param array $parameters */ private function replaceParameters(string $queryString, array $parameters): string { @@ -248,7 +266,9 @@ private function replaceParameters(string $queryString, array $parameters): stri return $haystack; }; - foreach ($parameters as $placeholderKey => $value) { + foreach ($parameters as $placeholderKey => $parameter) { + $value = $parameter->simulatedValue; + if (\is_string($value)) { // XXX escaping $value = "'".$value."'"; @@ -258,10 +278,10 @@ private function replaceParameters(string $queryString, array $parameters): stri $value = (string) $value; } - if (\is_int($placeholderKey)) { - $queryString = $replaceFirst($queryString, '?', $value); - } else { + if (\is_string($placeholderKey)) { $queryString = str_replace($placeholderKey, $value, $queryString); + } else { + $queryString = $replaceFirst($queryString, '?', $value); } }