Skip to content

Commit

Permalink
db: Cleanup parent/child relations in matching models
Browse files Browse the repository at this point in the history
The previous relations didn't work as expected.
Now, filtering with `child.host.name` or
`parent.service.name` works fine.
  • Loading branch information
nilmerg committed Sep 17, 2024
1 parent 6d15b8e commit b5a4caa
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 30 deletions.
14 changes: 10 additions & 4 deletions library/Icingadb/Model/DependencyEdge.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
* @property string $from_node_id
* @property ?string $dependency_id
*
* @property DependencyNode|Query $from
* @property DependencyNode|Query $to
* @property DependencyNode|Query $child
* @property DependencyNode|Query $parent
* @property (?Dependency)|Query $dependency
*/
class DependencyEdge extends Model
Expand Down Expand Up @@ -53,11 +53,17 @@ public function createBehaviors(Behaviors $behaviors): void

public function createRelations(Relations $relations): void
{
$relations->belongsTo('from', DependencyNode::class)
$relations->belongsTo('child', DependencyNode::class)
->setCandidateKey('from_node_id');
$relations->belongsTo('to', DependencyNode::class)
$relations->belongsTo('parent', DependencyNode::class)
->setCandidateKey('to_node_id');
$relations->belongsTo('dependency', Dependency::class)
->setJoinType('LEFT');

// "from" and "to" are only necessary for sub-query filters.
$relations->belongsTo('from', DependencyNode::class)
->setCandidateKey('from_node_id');
$relations->belongsTo('to', DependencyNode::class)
->setCandidateKey('to_node_id');
}
}
25 changes: 13 additions & 12 deletions library/Icingadb/Model/DependencyNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Icinga\Module\Icingadb\Model;

use Icinga\Module\Icingadb\Model\Behavior\ReRoute;
use ipl\Orm\Behavior\Binary;
use ipl\Orm\Behaviors;
use ipl\Orm\Model;
Expand All @@ -23,8 +24,6 @@
* @property (?RedundancyGroup)|Query $redundancy_group
* @property (?DependencyEdge)|Query $from
* @property (?DependencyEdge)|Query $to
* @property (?DependencyNode)|Query $child
* @property (?DependencyNode)|Query $parent
*/
class DependencyNode extends Model
{
Expand Down Expand Up @@ -56,6 +55,10 @@ public function createBehaviors(Behaviors $behaviors): void
'service_id',
'redundancy_group_id'
]));
$behaviors->add(new ReRoute([
'child' => 'to.from',
'parent' => 'from.to'
]));
}

public function createRelations(Relations $relations): void
Expand All @@ -74,15 +77,13 @@ public function createRelations(Relations $relations): void
->setForeignKey('to_node_id')
->setJoinType('LEFT');

$relations->belongsToMany('child', self::class)
->through(DependencyEdge::class)
->setForeignKey('to_node_id')
->setTargetForeignKey('from_node_id')
->setJoinType('LEFT');
$relations->belongsToMany('parent', self::class)
->through(DependencyEdge::class)
->setForeignKey('from_node_id')
->setTargetForeignKey('to_node_id')
->setJoinType('LEFT');
// TODO: This self join is only a work-around as when selecting nodes and filtering by child or parent,
// the ORM wants to join the base table as usual in case a sub-query is used. Though, in this case
// resolving e.g. child to "to.from" is reversed in a sub-query to "from.to" and the ORM does not
// detect that "to" is already the link to the base table.
// Given the path "dependency_node.to.from.host", the sub-query uses "host.from.to.dependency_node".
// "to.dependency_node" is the crucial part, as "dependency_node" is said self-join.
$relations->hasOne('dependency_node', self::class)
->setForeignKey('id');
}
}
15 changes: 11 additions & 4 deletions library/Icingadb/Model/Host.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@ public function createBehaviors(Behaviors $behaviors)
]));

$behaviors->add(new ReRoute([
'child' => 'dependency_node.child',
'parent' => 'dependency_node.parent',
'child' => 'to.from',
'parent' => 'from.to',
'servicegroup' => 'service.servicegroup',
'user' => 'notification.user',
'usergroup' => 'notification.usergroup'
Expand Down Expand Up @@ -237,8 +237,6 @@ public function createDefaults(Defaults $defaults)

public function createRelations(Relations $relations)
{
$relations->belongsTo('dependency_node', DependencyNode::class)
->setJoinType('LEFT');
$relations->belongsTo('environment', Environment::class);
$relations->belongsTo('eventcommand', Eventcommand::class);
$relations->belongsTo('checkcommand', Checkcommand::class);
Expand Down Expand Up @@ -274,5 +272,14 @@ public function createRelations(Relations $relations)
$relations->hasMany('notification', Notification::class)->setJoinType('LEFT');
$relations->hasMany('notification_history', NotificationHistory::class);
$relations->hasMany('service', Service::class)->setJoinType('LEFT');

$relations->belongsToMany('from', DependencyEdge::class)
->setTargetCandidateKey('from_node_id')
->setTargetForeignKey('id')
->through(DependencyNode::class);
$relations->belongsToMany('to', DependencyEdge::class)
->setTargetCandidateKey('to_node_id')
->setTargetForeignKey('id')
->through(DependencyNode::class);
}
}
19 changes: 13 additions & 6 deletions library/Icingadb/Model/RedundancyGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
*
* @property (?RedundancyGroupState)|Query $state
* @property Dependency|Query $dependency
* @property DependencyEdge|Query $from
* @property DependencyEdge|Query $to
*/
class RedundancyGroup extends Model
{
Expand Down Expand Up @@ -48,20 +50,25 @@ public function createBehaviors(Behaviors $behaviors): void
'id'
]));
$behaviors->add(new ReRoute([
'child' => 'dependency_node.child',
'parent' => 'dependency_node.parent'
'child' => 'to.from',
'parent' => 'from.to'
]));
}

public function createRelations(Relations $relations): void
{
$relations->belongsTo('dependency_node', DependencyNode::class)
->setForeignKey('redundancy_group_id')
->setCandidateKey('id');

$relations->hasOne('state', RedundancyGroupState::class)
->setJoinType('LEFT');

$relations->hasMany('dependency', Dependency::class);

$relations->belongsToMany('from', DependencyEdge::class)
->setTargetCandidateKey('from_node_id')
->setTargetForeignKey('id')
->through(DependencyNode::class);
$relations->belongsToMany('to', DependencyEdge::class)
->setTargetCandidateKey('to_node_id')
->setTargetForeignKey('id')
->through(DependencyNode::class);
}
}
15 changes: 11 additions & 4 deletions library/Icingadb/Model/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ public function createBehaviors(Behaviors $behaviors)
]));

$behaviors->add(new ReRoute([
'child' => 'dependency_node.child',
'parent' => 'dependency_node.parent',
'child' => 'to.from',
'parent' => 'from.to',
'user' => 'notification.user',
'usergroup' => 'notification.usergroup'
]));
Expand Down Expand Up @@ -224,8 +224,6 @@ public function createDefaults(Defaults $defaults)

public function createRelations(Relations $relations)
{
$relations->belongsTo('dependency_node', DependencyNode::class)
->setJoinType('LEFT');
$relations->belongsTo('environment', Environment::class);
$relations->belongsTo('host', Host::class)->setJoinType('LEFT');
$relations->belongsTo('checkcommand', Checkcommand::class);
Expand Down Expand Up @@ -263,5 +261,14 @@ public function createRelations(Relations $relations)
$relations->hasMany('history', History::class);
$relations->hasMany('notification', Notification::class)->setJoinType('LEFT');
$relations->hasMany('notification_history', NotificationHistory::class);

$relations->belongsToMany('from', DependencyEdge::class)
->setTargetCandidateKey('from_node_id')
->setTargetForeignKey('id')
->through(DependencyNode::class);
$relations->belongsToMany('to', DependencyEdge::class)
->setTargetCandidateKey('to_node_id')
->setTargetForeignKey('id')
->through(DependencyNode::class);
}
}

0 comments on commit b5a4caa

Please sign in to comment.