Skip to content

Commit

Permalink
Introduced a dagRelationsOf scope to get relations (ancestors *and* d…
Browse files Browse the repository at this point in the history
…escendants), added new tests, minor code/test cleanup.
  • Loading branch information
telkins committed Jul 31, 2020
1 parent cf7b80b commit fc6f3ee
Show file tree
Hide file tree
Showing 2 changed files with 380 additions and 155 deletions.
49 changes: 38 additions & 11 deletions src/Models/Traits/IsDagManaged.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ trait IsDagManaged
*/
public function scopeDagDescendantsOf($query, $modelId, string $source, ?int $maxHops = null)
{
$this->scopeDagRelationsOf($query, $modelId, $source, true, $maxHops);
$this->queryDagRelations($query, $modelId, $source, true, $maxHops);
}

/**
Expand All @@ -27,7 +27,20 @@ public function scopeDagDescendantsOf($query, $modelId, string $source, ?int $ma
*/
public function scopeDagAncestorsOf($query, $modelId, string $source, ?int $maxHops = null)
{
$this->scopeDagRelationsOf($query, $modelId, $source, false, $maxHops);
$this->queryDagRelations($query, $modelId, $source, false, $maxHops);
}

/**
* Scope a query to only include models that are related to (either descendants *or* ancestors) the specified model ID.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param int|array $modelId
* @param string $source
*/
public function scopeDagRelationsOf($query, $modelId, string $source, ?int $maxHops = null)
{
$this->queryDagRelations($query, $modelId, $source, false, $maxHops);
$this->queryDagRelations($query, $modelId, $source, true, $maxHops, true);
}

/**
Expand All @@ -38,18 +51,15 @@ public function scopeDagAncestorsOf($query, $modelId, string $source, ?int $maxH
* @param string $source
* @param bool $down
*/
public function scopeDagRelationsOf($query, $modelId, string $source, bool $down, ?int $maxHops = null)
protected function queryDagRelations($query, $modelId, string $source, bool $down, ?int $maxHops = null, bool $or = false)
{
if (! is_int($modelId) && ! is_array($modelId)) {
throw new InvalidArgumentException('Argument, $modelId, must be of type integer or array.');
}
$this->guardAgainstInvalidModelId($modelId);

$maxHopsConfig = config('laravel-dag-manager.max_hops');
$maxHops = $maxHops ?? $maxHopsConfig; // prefer input over config
$maxHops = min($maxHops, $maxHopsConfig); // no larger than config
$maxHops = max($maxHops, 0); // no smaller than zero
$maxHops = $this->maxHops($maxHops);

$query->whereIn($this->getQualifiedKeyName(), function ($query) use ($modelId, $source, $maxHops, $down) {
$method = $or ? 'orWhereIn' : 'whereIn';

$query->$method($this->getQualifiedKeyName(), function ($query) use ($modelId, $source, $maxHops, $down) {
$selectField = $down ? 'start_vertex' : 'end_vertex';
$whereField = $down ? 'end_vertex' : 'start_vertex';

Expand All @@ -66,4 +76,21 @@ public function scopeDagRelationsOf($query, $modelId, string $source, bool $down
});
});
}

protected function guardAgainstInvalidModelId($modelId)
{
if (! is_int($modelId) && ! is_array($modelId)) {
throw new InvalidArgumentException('Argument, $modelId, must be of type integer or array.');
}
}

protected function maxHops(?int $maxHops): int
{
$maxHopsConfig = config('laravel-dag-manager.max_hops');
$maxHops = $maxHops ?? $maxHopsConfig; // prefer input over config
$maxHops = min($maxHops, $maxHopsConfig); // no larger than config
$maxHops = max($maxHops, 0); // no smaller than zero

return $maxHops;
}
}
Loading

0 comments on commit fc6f3ee

Please sign in to comment.