Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"php": "^7.4 || ^8.0",
"composer-runtime-api": "^2.0",
"composer/semver": "^3.2",
"phpstan/phpstan": "^2.1.2"
"phpstan/phpstan": "^2.3.0"
},
"require-dev": {
"ext-mysqli": "*",
Expand Down
2 changes: 1 addition & 1 deletion config/extensions.neon
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,4 @@ services:
-
class: staabm\PHPStanDba\Extensions\DbSchemaResultCacheMetaExtension
tags:
- phpstan.resultCacheMetaExtension
- phpstan.resultCacheValueExtension
31 changes: 25 additions & 6 deletions src/Extensions/DbSchemaResultCacheMetaExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,32 @@

namespace staabm\PHPStanDba\Extensions;

use PHPStan\Analyser\ResultCache\ResultCacheMetaExtension;
use PHPStan\Analyser\DependencyTracker;
use PHPStan\Analyser\ResultCache\ResultCacheValueExtension;
use PHPStan\Analyser\Scope;
use staabm\PHPStanDba\DbaException;
use staabm\PHPStanDba\QueryReflection\QueryReflection;

// @phpstan-ignore class.implementsDeprecatedInterface
final class DbSchemaResultCacheMetaExtension implements ResultCacheMetaExtension
final class DbSchemaResultCacheMetaExtension implements ResultCacheValueExtension
{
public function getKey(): string
private const SCHEMA_KEY = 'schema';

/**
* Marks the currently analysed file as dependent on the database schema.
*/
public static function trackSchemaDependency(Scope $scope): void
{
return 'phpstan-dba-schema-hash';
if ($scope instanceof DependencyTracker) {
$scope->trackValueDependency(self::class, self::SCHEMA_KEY);
}
}

public function getHash(): string
public function getValue(string $key): string
{
try {
$queryReflection = new QueryReflection();
$schemaHasher = $queryReflection->getSchemaHasher();

return $schemaHasher->hashDb();
} catch (DbaException $e) {
// don't break the whole process when reflector is not
Expand All @@ -29,4 +38,14 @@ public function getHash(): string
return 'reflector-not-initialized';
}
}

public function keyToResultCache(string $key): string
{
return $key;
}

public function keyFromResultCache(string $storedKey): string
{
return $storedKey;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
return null;
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

$queryReflection = new QueryReflection();
$queryString = $queryReflection->resolveQueryString($args[0]->value, $scope);
if (null === $queryString) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
return null;
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

try {
return $this->inferType($methodReflection, $args[0]->value, $scope);
} catch (UnresolvableQueryException $exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
return null;
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

$params = null;
if (\count($args) > 1) {
$params = $args[1]->value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
return null;
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

$params = null;
if (\count($args) > 1) {
$params = $args[1]->value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
return null;
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

try {
return $this->inferType($args[0]->value, $scope);
} catch (UnresolvableQueryException $exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
return null;
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

try {
return $this->inferType($args[0]->value, $scope);
} catch (UnresolvableQueryException $exception) {
Expand Down
2 changes: 2 additions & 0 deletions src/Extensions/DoctrineResultDynamicReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
return null;
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

try {
return $this->inferType($methodReflection, $methodCall, $scope);
} catch (UnresolvableQueryException $exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
return null;
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

try {
return $this->inferType($methodReflection, $methodCall, $args[0]->value, $scope);
} catch (UnresolvableQueryException $exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
return $defaultReturn;
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

$argType = $scope->getType($args[1]->value);

return $this->inferType($argType);
Expand All @@ -86,6 +88,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
return $defaultReturn;
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

$argType = $scope->getType($args[0]->value);

return $this->inferType($argType);
Expand Down
4 changes: 4 additions & 0 deletions src/Extensions/MysqliQueryDynamicReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
return $defaultReturn;
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

try {
$resultType = $this->inferResultType($args[1]->value, $scope);
if (null !== $resultType) {
Expand Down Expand Up @@ -98,6 +100,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
return $defaultReturn;
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

try {
$resultType = $this->inferResultType($args[0]->value, $scope);
if (null !== $resultType) {
Expand Down
2 changes: 2 additions & 0 deletions src/Extensions/PdoPrepareDynamicReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
return $defaultReturn;
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

try {
$resultType = $this->inferType($args[0]->value, $scope);
if (null !== $resultType) {
Expand Down
2 changes: 2 additions & 0 deletions src/Extensions/PdoQueryDynamicReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
return $defaultReturn;
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

try {
$resultType = $this->inferType($methodCall, $args[0]->value, $scope);
if (null !== $resultType) {
Expand Down
2 changes: 2 additions & 0 deletions src/Extensions/PdoQuoteDynamicReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
return $defaultReturn;
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

try {
$stringType = $this->inferType($methodCall, $scope);
if (null !== $stringType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
$statementType = $scope->getType($methodCall->var);

if ($statementType instanceof PdoStatementObjectType) {
DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

$arrays = $statementType->newWithFetchType(QueryReflector::FETCH_TYPE_NUMERIC)->getRowType()->getConstantArrays();
if (count($arrays) === 1) {
$rowType = $arrays[0];
Expand Down
2 changes: 2 additions & 0 deletions src/Extensions/PdoStatementExecuteTypeSpecifyingExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public function specifyTypes(MethodReflection $methodReflection, MethodCall $nod
// keep original param name because named-parameters
$methodCall = $node;

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

try {
$inferredType = $this->inferStatementType($methodReflection, $methodCall, $scope);
} catch (UnresolvableQueryException $e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
$methodReflection->getVariants()
)->getReturnType();

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

try {
$resultType = $this->inferType($methodReflection, $methodCall, $scope);
if (null !== $resultType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public function isMethodSupported(MethodReflection $methodReflection): bool

public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): ?Type
{
DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

try {
return $this->inferType($methodReflection, $methodCall, $scope);
} catch (UnresolvableQueryException $exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public function specifyTypes(MethodReflection $methodReflection, MethodCall $nod
$statementType = $scope->getType($methodCall->var);

if ($statementType instanceof PdoStatementObjectType) {
DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

$reducedType = $this->reduceType($methodCall, $statementType, $scope);

if (null !== $reducedType) {
Expand Down
3 changes: 3 additions & 0 deletions src/Rules/DoctrineKeyValueStyleRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\VerbosityLevel;
use staabm\PHPStanDba\Extensions\DbSchemaResultCacheMetaExtension;
use staabm\PHPStanDba\QueryReflection\QueryReflection;

/**
Expand Down Expand Up @@ -111,6 +112,8 @@ public function processNode(Node $callLike, Scope $scope): array
return [];
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

// Reorder arguments to account for named parameters
$parametersAcceptor = ParametersAcceptorSelector::selectFromArgs(
$scope,
Expand Down
3 changes: 3 additions & 0 deletions src/Rules/PdoStatementExecuteMethodRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\ObjectType;
use staabm\PHPStanDba\Extensions\DbSchemaResultCacheMetaExtension;
use staabm\PHPStanDba\PdoReflection\PdoStatementReflection;
use staabm\PHPStanDba\QueryReflection\PlaceholderValidation;
use staabm\PHPStanDba\QueryReflection\QueryReflection;
Expand Down Expand Up @@ -72,6 +73,8 @@ private function checkErrors(MethodReflection $methodReflection, MethodCall $met
return [];
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

$args = $methodCall->getArgs();
if (\count($args) < 1) {
$parameterKeys = [];
Expand Down
3 changes: 3 additions & 0 deletions src/Rules/QueryPlanAnalyzerRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\ShouldNotHappenException;
use PHPStan\Type\ObjectType;
use staabm\PHPStanDba\Extensions\DbSchemaResultCacheMetaExtension;
use staabm\PHPStanDba\QueryReflection\QueryReflection;
use staabm\PHPStanDba\Tests\QueryPlanAnalyzerRuleTest;
use staabm\PHPStanDba\UnresolvableQueryException;
Expand Down Expand Up @@ -107,6 +108,8 @@ public function processNode(Node $callLike, Scope $scope): array
return [];
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

try {
return $this->analyze($callLike, $scope);
} catch (UnresolvableQueryException $exception) {
Expand Down
3 changes: 3 additions & 0 deletions src/Rules/SyntaxErrorInDibiPreparedStatementMethodRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\ObjectType;
use staabm\PHPStanDba\DibiReflection\DibiReflection;
use staabm\PHPStanDba\Extensions\DbSchemaResultCacheMetaExtension;
use staabm\PHPStanDba\QueryReflection\DbaApi;
use staabm\PHPStanDba\QueryReflection\QueryReflection;
use staabm\PHPStanDba\QueryReflection\QueryReflector;
Expand Down Expand Up @@ -110,6 +111,8 @@ private function checkErrors(CallLike $callLike, Scope $scope, MethodReflection
return [];
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

$queryReflection = new QueryReflection(new DbaApi(DbaApi::API_DIBI));
$queryParameters = [];
$errors = [];
Expand Down
3 changes: 3 additions & 0 deletions src/Rules/SyntaxErrorInPreparedStatementMethodRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use PHPStan\ShouldNotHappenException;
use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectType;
use staabm\PHPStanDba\Extensions\DbSchemaResultCacheMetaExtension;
use staabm\PHPStanDba\QueryReflection\PlaceholderValidation;
use staabm\PHPStanDba\QueryReflection\QueryReflection;
use staabm\PHPStanDba\UnresolvableQueryException;
Expand Down Expand Up @@ -120,6 +121,8 @@ private function checkErrors(CallLike $callLike, Scope $scope): array
return [];
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

$queryExpr = $args[0]->value;
$queryReflection = new QueryReflection();

Expand Down
3 changes: 3 additions & 0 deletions src/Rules/SyntaxErrorInQueryFunctionRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\ShouldNotHappenException;
use staabm\PHPStanDba\Extensions\DbSchemaResultCacheMetaExtension;
use staabm\PHPStanDba\QueryReflection\QueryReflection;
use staabm\PHPStanDba\Tests\SyntaxErrorInQueryFunctionRuleTest;
use staabm\PHPStanDba\UnresolvableQueryException;
Expand Down Expand Up @@ -81,6 +82,8 @@ public function processNode(Node $node, Scope $scope): array
return [];
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

$queryExpr = $args[$queryArgPosition]->value;
$queryReflection = new QueryReflection();

Expand Down
3 changes: 3 additions & 0 deletions src/Rules/SyntaxErrorInQueryMethodRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\ShouldNotHappenException;
use staabm\PHPStanDba\Extensions\DbSchemaResultCacheMetaExtension;
use staabm\PHPStanDba\QueryReflection\QueryReflection;
use staabm\PHPStanDba\UnresolvableQueryException;

Expand Down Expand Up @@ -102,6 +103,8 @@ public function processNode(Node $callLike, Scope $scope): array
return [];
}

DbSchemaResultCacheMetaExtension::trackSchemaDependency($scope);

$queryExpr = $args[$queryArgPosition]->value;
$queryReflection = new QueryReflection();

Expand Down
Loading