#325 significant speed-up to Device > Ports tab (thx to T. Teräs)

This commit is contained in:
Oliver Gorwits
2017-07-09 10:03:52 +01:00
parent 46c0b6b6e0
commit 4e5b544b9c
6 changed files with 69 additions and 69 deletions

View File

@@ -91,26 +91,11 @@ __PACKAGE__->belongs_to( device => 'App::Netdisco::DB::Result::Device', 'ip' );
Returns the set of C<device_port_vlan> entries associated with this Port.
These will be both tagged and untagged. Use this relation in search conditions.
See also C<all_port_vlans>.
=cut
__PACKAGE__->has_many( port_vlans => 'App::Netdisco::DB::Result::DevicePortVlan',
{ 'foreign.ip' => 'self.ip', 'foreign.port' => 'self.port' } );
=head2 all_port_vlans
Returns the set of C<device_port_vlan> entries associated with this Port.
These will be both tagged and untagged. Use this relation when prefetching related
C<device_port_vlan> rows.
See also C<port_vlans>.
=cut
__PACKAGE__->has_many( all_port_vlans => 'App::Netdisco::DB::Result::DevicePortVlan',
{ 'foreign.ip' => 'self.ip', 'foreign.port' => 'self.port' } );
=head2 nodes / active_nodes / nodes_with_age / active_nodes_with_age
Returns the set of Nodes whose MAC addresses are associated with this Device
@@ -241,10 +226,10 @@ __PACKAGE__->belongs_to( neighbor_alias => 'App::Netdisco::DB::Result::DeviceIp'
sub {
my $args = shift;
return {
"$args->{foreign_alias}.ip" => { '=' =>
"$args->{foreign_alias}.alias" => { '=' =>
$args->{self_resultsource}->schema->resultset('DeviceIp')
->search({alias => { -ident => "$args->{self_alias}.remote_ip"}},
{rows => 1, columns => 'ip', alias => 'devipsub'})->as_query }
{rows => 1, columns => 'alias', alias => 'devipsub'})->as_query }
};
},
{ join_type => 'LEFT' },
@@ -252,7 +237,7 @@ __PACKAGE__->belongs_to( neighbor_alias => 'App::Netdisco::DB::Result::DeviceIp'
=head2 vlans
As compared to C<port_vlans>, this relationship returns a set of VLAN
As compared to C<port_vlans>, this relationship returns a set of Device VLAN
row objects for the VLANs on the given port, which might be more useful if you
want to find out details such as the VLAN name.
@@ -260,7 +245,7 @@ See also C<vlan_count>.
=cut
__PACKAGE__->many_to_many( vlans => 'all_port_vlans', 'vlan' );
__PACKAGE__->many_to_many( vlans => 'port_vlans', 'vlan' );
=head2 oui

View File

@@ -96,7 +96,7 @@ sub search_aliases {
{
order_by => [qw/ me.dns me.ip /],
join => 'device_ips',
distinct => 1,
group_by => 'me.ip',
}
);
}

View File

@@ -113,7 +113,32 @@ get '/ajax/content/device/ports' => require_login sub {
$set = $set->search({-or => \@combi});
}
# get aggregate master status
# so far only the basic device_port data
# now begin to join tables depending on the selected columns/options
# get vlans on the port
# leave this query dormant (lazy) unless c_vmember is set
my $vlans = $set->search({}, {
select => [
'port',
{ array_agg => 'port_vlans.vlan', -as => 'vlan_set' },
{ count => 'port_vlans.vlan', -as => 'vlan_count' },
],
join => 'port_vlans',
group_by => 'me.port',
});
if (param('c_vmember')) {
$vlans = { map {(
$_->port => {
# DBIC smart enough to work out this should be an arrayref :)
vlan_set => $_->get_column('vlan_set'),
vlan_count => $_->get_column('vlan_count'),
},
)} $vlans->all };
}
# get aggregate master status (self join)
$set = $set->search({}, {
'join' => 'agg_master',
'+select' => [qw/agg_master.up_admin agg_master.up/],
@@ -123,17 +148,6 @@ get '/ajax/content/device/ports' => require_login sub {
# make sure query asks for formatted timestamps when needed
$set = $set->with_times if param('c_lastchange');
# get vlans on the port, if there aren't too many
my $port_cnt = $device->ports->count() || 1;
my $vlan_cnt = $device->port_vlans->count() || 1;
my $vmember_ok =
(($vlan_cnt / $port_cnt) <= setting('devport_vlan_limit'));
if ($vmember_ok) {
$set = $set->search_rs({}, { prefetch => 'all_port_vlans' })->with_vlan_count
if param('c_vmember');
}
# what kind of nodes are we interested in?
my $nodes_name = (param('n_archived') ? 'nodes' : 'active_nodes');
$nodes_name .= '_with_age' if param('n_age');
@@ -144,28 +158,35 @@ get '/ajax/content/device/ports' => require_login sub {
if (param('c_nodes')) {
# retrieve active/all connected nodes, if asked for
$set = $set->search_rs({}, { prefetch => [{$nodes_name => $ips_name}] });
$set = $set->search_rs({}, { order_by => ["${nodes_name}.vlan", "${nodes_name}.mac", "${ips_name}.ip"] });
$set = $set->search({}, { prefetch => [{$nodes_name => $ips_name}] });
$set = $set->search({}, { order_by => ["${nodes_name}.vlan", "${nodes_name}.mac", "${ips_name}.ip"] });
# retrieve wireless SSIDs, if asked for
$set = $set->search_rs({}, { prefetch => [{$nodes_name => 'wireless'}] })
$set = $set->search({}, { prefetch => [{$nodes_name => 'wireless'}] })
if param('n_ssid');
# retrieve NetBIOS, if asked for
$set = $set->search_rs({}, { prefetch => [{$nodes_name => 'netbios'}] })
$set = $set->search({}, { prefetch => [{$nodes_name => 'netbios'}] })
if param('n_netbios');
# retrieve vendor, if asked for
$set = $set->search_rs({}, { prefetch => [{$nodes_name => 'oui'}] })
$set = $set->search({}, { prefetch => [{$nodes_name => 'oui'}] })
if param('n_vendor');
}
# retrieve SSID, if asked for
$set = $set->search({}, { prefetch => 'ssid' }) if param('c_ssid');
$set = $set->search({}, { prefetch => 'ssid' })
if param('c_ssid');
# retrieve neighbor devices, if asked for
$set = $set->search_rs({}, { prefetch => [{neighbor_alias => 'device'}] })
if param('c_neighbors');
#$set = $set->search({}, { prefetch => [{neighbor_alias => 'device'}] })
# if param('c_neighbors');
# retrieve neighbor devices, if asked for
$set = $set->search({}, {
join => 'neighbor_alias',
'+select' => ['neighbor_alias.ip', 'neighbor_alias.dns'],
'+as' => ['neighbor_ip', 'neighbor_dns'],
}) if param('c_neighbors');
# sort ports (empty set would be a 'no records' msg)
my $results = [ sort { &App::Netdisco::Util::Web::sort_port($a->port, $b->port) } $set->all ];
@@ -177,7 +198,7 @@ get '/ajax/content/device/ports' => require_login sub {
nodes => $nodes_name,
ips => $ips_name,
device => $device,
vmember_ok => $vmember_ok,
vlans => $vlans,
}, { layout => undef };
}
else {
@@ -187,6 +208,7 @@ get '/ajax/content/device/ports' => require_login sub {
nodes => $nodes_name,
ips => $ips_name,
device => $device,
vlans => $vlans,
}, { layout => undef };
}
};