1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-02-04 23:14:05 +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 = [...$visitedTables, $table];
// Initialize the length variables with maximum values
$shortestLength = PHP_INT_MAX;
$shortestNonNullableLength = PHP_INT_MAX;
$shortestPath = null;
$shortestNonNullablePath = null;
$shortestPath = [];
$hasRecursiveRelationships = false;
$hasValidPaths = false;
@ -443,20 +439,9 @@ class TableRLSManager implements RLSPolicyManager
$hasValidPaths = true;
$path = $this->buildPath($foreign, $foreignPath);
$length = count($path['steps']);
$isNullable = $this->isPathNullable($path['steps']);
// Update shortest path
if ($length < $shortestLength) {
$shortestLength = $length;
if ($this->determineBetterPath($path, $shortestPath)) {
$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.
return $finalPath;
} else {
$finalPath = $shortestNonNullablePath ?? $shortestPath ?? [
$finalPath = $shortestPath ? $shortestPath : [
'dead_end' => true,
'recursion' => false,
'steps' => [],
@ -513,4 +498,28 @@ class TableRLSManager implements RLSPolicyManager
'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']);
}
}