1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-02-05 06:24:04 +00:00

Improve code for determining the shortest path

This commit is contained in:
lukinovec 2025-05-29 12:35:41 +02:00
parent 1bfac014ab
commit 973f7994c3

View file

@ -411,11 +411,7 @@ class TableRLSManager implements RLSPolicyManager
array $visitedTables array $visitedTables
): array { ): array {
$visitedTables = [...$visitedTables, $table]; $visitedTables = [...$visitedTables, $table];
// Initialize the length variables with maximum values $shortestPath = [];
$shortestLength = PHP_INT_MAX;
$shortestNonNullableLength = PHP_INT_MAX;
$shortestPath = null;
$shortestNonNullablePath = null;
$hasRecursiveRelationships = false; $hasRecursiveRelationships = false;
$hasValidPaths = false; $hasValidPaths = false;
@ -443,20 +439,9 @@ class TableRLSManager implements RLSPolicyManager
$hasValidPaths = true; $hasValidPaths = true;
$path = $this->buildPath($foreign, $foreignPath); $path = $this->buildPath($foreign, $foreignPath);
$length = count($path['steps']); if ($this->determineBetterPath($path, $shortestPath)) {
$isNullable = $this->isPathNullable($path['steps']);
// Update shortest path
if ($length < $shortestLength) {
$shortestLength = $length;
$shortestPath = $path; $shortestPath = $path;
} }
// Update shortest non-nullable path
if (! $isNullable && $length < $shortestNonNullableLength) {
$shortestNonNullableLength = $length;
$shortestNonNullablePath = $path;
}
} }
} }
@ -475,7 +460,7 @@ class TableRLSManager implements RLSPolicyManager
// If the recursive path got cached, the path leading directly through tenants would never be found. // If the recursive path got cached, the path leading directly through tenants would never be found.
return $finalPath; return $finalPath;
} else { } else {
$finalPath = $shortestNonNullablePath ?? $shortestPath ?? [ $finalPath = $shortestPath ? $shortestPath : [
'dead_end' => true, 'dead_end' => true,
'recursion' => false, 'recursion' => false,
'steps' => [], 'steps' => [],
@ -513,4 +498,28 @@ class TableRLSManager implements RLSPolicyManager
'steps' => array_merge([$constraint], $subPath['steps']) 'steps' => array_merge([$constraint], $subPath['steps'])
]; ];
} }
/**
* Determine if the passed path is better than the current shortest path.
*
* Non-nullable paths are preferred over nullable paths.
* From paths of the same nullability, the shorter will be preferred.
*/
protected function determineBetterPath(array $path, array $currentBestPath): bool
{
if (! $currentBestPath) {
return true;
}
$pathIsNullable = $this->isPathNullable($path['steps']);
$bestPathIsNullable = $this->isPathNullable($currentBestPath['steps']);
// Prefer non-nullable
if ($pathIsNullable !== $bestPathIsNullable) {
return ! $pathIsNullable;
}
// Prefer shorter
return count($path['steps']) < count($currentBestPath['steps']);
}
} }