Skip to content

Commit

Permalink
Optimized Ancestors + Descendants components
Browse files Browse the repository at this point in the history
  • Loading branch information
MGeurts committed Nov 6, 2024
1 parent 1b47c25 commit db4e192
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 40 deletions.
80 changes: 56 additions & 24 deletions app/Livewire/People/Ancestors.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@

class Ancestors extends Component
{
// ------------------------------------------------------------------------------
public $person;

// ------------------------------------------------------------------------------
public Collection $ancestors;

public int $count_min = 1;
Expand All @@ -34,51 +32,85 @@ class Ancestors extends Component
// ...
// --------------------------------------------------------------------------------------------------------------------

/**
* Set up the component data.
*/
public function mount(): void
{
$this->ancestors = collect(DB::select("
WITH RECURSIVE ancestors AS (
SELECT
id, firstname, surname, sex, father_id, mother_id, dod, yod, team_id, photo,
0 AS degree,
CAST(id AS CHAR(1024)) AS sequence
FROM people
WHERE deleted_at IS NULL AND id = '" . $this->person->id . "'
UNION ALL
SELECT p.id, p.firstname, p.surname, p.sex, p.father_id, p.mother_id, p.dod, p.yod, p.team_id, p.photo,
degree + 1 AS degree,
CAST(CONCAT(a.sequence, ',', p.id) AS CHAR(1024)) AS sequence
FROM people p, ancestors a
WHERE deleted_at IS NULL AND (p.id = a.father_id OR p.id = a.mother_id) AND degree < '" . $this->count_max - 1 . "'
)
SELECT * FROM ancestors ORDER BY degree, sex DESC;
"));
$this->loadAncestors();
}

$this->count_max = $this->ancestors->max('degree') <= $this->count_max ? $this->ancestors->max('degree') + 1 : $this->count_max;
/**
* Load ancestors from the database with recursion.
*/
private function loadAncestors(): void
{
$this->ancestors = collect(DB::select($this->getRecursiveQuery()));

$maxDegree = $this->ancestors->max('degree');
$this->count_max = min($maxDegree + 1, $this->count_max);

if ($this->count > $this->count_max) {
$this->count = $this->count_max;
}
}

/**
* Build the recursive query for ancestors.
*/
private function getRecursiveQuery(): string
{
$personId = $this->person->id;
$countMax = $this->count_max;

return "
WITH RECURSIVE ancestors AS (
SELECT
id, firstname, surname, sex, father_id, mother_id, dod, yod, team_id, photo,
0 AS degree,
CAST(id AS CHAR(1024)) AS sequence
FROM people
WHERE deleted_at IS NULL AND id = $personId
UNION ALL
SELECT
p.id, p.firstname, p.surname, p.sex, p.father_id, p.mother_id, p.dod, p.yod, p.team_id, p.photo,
a.degree + 1 AS degree,
CAST(CONCAT(a.sequence, ',', p.id) AS CHAR(1024)) AS sequence
FROM people p
JOIN ancestors a ON p.id = a.father_id OR p.id = a.mother_id
WHERE p.deleted_at IS NULL
AND a.degree < $countMax
)
SELECT * FROM ancestors ORDER BY degree, sex DESC;
";
}

/**
* Increment the count of ancestors displayed.
*/
public function increment(): void
{
if ($this->count < $this->count_max) {
$this->count++;
}
}

/**
* Decrement the count of ancestors displayed.
*/
public function decrement(): void
{
if ($this->count > $this->count_min) {
$this->count--;
}
}

// ------------------------------------------------------------------------------
/**
* Render the Livewire component view.
*/
public function render(): View
{
return view('livewire.people.ancestors');
Expand Down
64 changes: 48 additions & 16 deletions app/Livewire/People/Descendants.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@

class Descendants extends Component
{
// ------------------------------------------------------------------------------
public $person;

// ------------------------------------------------------------------------------
public Collection $descendants;

public int $count_min = 1;
Expand All @@ -34,51 +32,85 @@ class Descendants extends Component
// ...
// --------------------------------------------------------------------------------------------------------------------

/**
* Set up the component data.
*/
public function mount(): void
{
$this->descendants = collect(DB::select("
$this->loadDescendants();
}

/**
* Load descendants from the database with recursion.
*/
private function loadDescendants(): void
{
$this->descendants = collect(DB::select($this->getRecursiveQuery()));

$maxDegree = $this->descendants->max('degree');
$this->count_max = min($maxDegree + 1, $this->count_max);

if ($this->count > $this->count_max) {
$this->count = $this->count_max;
}
}

/**
* Build the recursive query for descendants.
*/
private function getRecursiveQuery(): string
{
$personId = $this->person->id;
$countMax = $this->count_max;

return "
WITH RECURSIVE descendants AS (
SELECT
id, firstname, surname, sex, father_id, mother_id, dod, yod, team_id, photo, dob, yob,
0 AS degree,
CAST(id AS CHAR(1024)) AS sequence
FROM people
WHERE deleted_at IS NULL AND id = '" . $this->person->id . "'
WHERE deleted_at IS NULL AND id = $personId
UNION ALL
SELECT p.id, p.firstname, p.surname, p.sex, p.father_id, p.mother_id, p.dod, p.yod, p.team_id, p.photo, p.dob, p.yob,
degree + 1 AS degree,
SELECT
p.id, p.firstname, p.surname, p.sex, p.father_id, p.mother_id, p.dod, p.yod, p.team_id, p.photo, p.dob, p.yob,
d.degree + 1 AS degree,
CAST(CONCAT(d.sequence, ',', p.id) AS CHAR(1024)) AS sequence
FROM people p, descendants d
WHERE deleted_at IS NULL AND (p.father_id = d.id OR p.mother_id = d.id) AND degree < '" . $this->count_max - 1 . "'
FROM people p
JOIN descendants d ON d.id = p.father_id OR d.id = p.mother_id
WHERE p.deleted_at IS NULL
AND d.degree < $countMax
)
SELECT * FROM descendants ORDER BY degree, dob, yob;
"));

$this->count_max = $this->descendants->max('degree') <= $this->count_max ? $this->descendants->max('degree') + 1 : $this->count_max;

if ($this->count > $this->count_max) {
$this->count = $this->count_max;
}
";
}

/**
* Increment the count of descendants displayed.
*/
public function increment(): void
{
if ($this->count < $this->count_max) {
$this->count++;
}
}

/**
* Decrement the count of descendants displayed.
*/
public function decrement(): void
{
if ($this->count > $this->count_min) {
$this->count--;
}
}

// ------------------------------------------------------------------------------
/**
* Render the Livewire component view.
*/
public function render(): View
{
return view('livewire.people.descendants');
Expand Down

0 comments on commit db4e192

Please sign in to comment.