efficient device delete which does not walk nodes

This commit is contained in:
Oliver Gorwits
2013-09-02 21:27:22 +01:00
parent 5807fd0323
commit be806d5ab1
16 changed files with 193 additions and 32 deletions

View File

@@ -130,7 +130,15 @@ sub _set_canonical_ip {
my $gone = $device->device_ips->delete;
debug sprintf ' [%s] device - removed %s aliases',
$oldip, $gone;
$device->delete;
# our special delete which is more efficient
schema('netdisco')->resultset('Device')
->search({ ip => $device->ip })->delete;
# a new row object from the old one
$device = schema('netdisco')->resultset('Device')
->new({ $device->get_columns });
debug sprintf ' [%s] device - deleted self', $oldip;
});

View File

@@ -78,7 +78,6 @@ __PACKAGE__->add_columns(
);
__PACKAGE__->set_primary_key("ip");
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:671/XuuvsO2aMB1+IRWFjg

View File

@@ -528,4 +528,44 @@ sub with_port_count {
});
}
=head1 SPECIAL METHODS
=head2 delete( \%options? )
Overrides the built-in L<DBIx::Class> delete method to more efficiently
handle the removal or archiving of nodes.
=cut
sub delete {
my $self = shift;
my $schema = $self->result_source->schema;
my $devices = $self->search(undef, { columns => 'ip' });
foreach my $set (qw/
Community
DeviceIp
DeviceVlan
DevicePower
DeviceModule
/) {
$schema->resultset($set)->search(
{ ip => { '-in' => $devices->as_query }},
)->delete;
}
$schema->resultset('Admin')->search({
device => { '-in' => $devices->as_query },
action => { '-like' => 'queued%' },
})->delete;
$schema->resultset('DevicePort')->search(
{ ip => { '-in' => $devices->as_query }},
)->delete(@_);
# now let DBIC do its thing
return $self->next::method();
}
1;

View File

@@ -133,4 +133,39 @@ sub with_vlan_count {
});
}
=head1 SPECIAL METHODS
=head2 delete( \%options? )
Overrides the built-in L<DBIx::Class> delete method to more efficiently
handle the removal or archiving of nodes.
=cut
sub delete {
my $self = shift;
my $schema = $self->result_source->schema;
my $ports = $self->search(undef, { columns => 'ip' });
foreach my $set (qw/
DevicePortPower
DevicePortVlan
DevicePortWireless
DevicePortSsid
DevicePortLog
/) {
$schema->resultset($set)->search(
{ ip => { '-in' => $ports->as_query }},
)->delete;
}
$schema->resultset('Node')->search(
{ switch => { '-in' => $ports->as_query }},
)->delete(@_);
# now let DBIC do its thing
return $self->next::method();
}
1;

View File

@@ -8,7 +8,9 @@ __PACKAGE__->load_components(qw/
+App::Netdisco::DB::ExplicitLocking
/);
=head1 search_by_mac( \%cond, \%attrs? )
=head1 ADDITIONAL METHODS
=head2 search_by_mac( \%cond, \%attrs? )
my $set = $rs->search_by_mac({mac => '00:11:22:33:44:55', active => 1});
@@ -63,4 +65,57 @@ sub search_by_mac {
->search($cond, $attrs);
}
=head1 SPECIAL METHODS
=head2 delete( \%options? )
Overrides the built-in L<DBIx::Class> delete method to more efficiently
handle the removal or archiving of nodes.
=cut
sub delete {
my $self = shift;
my ($opts) = @_;
my $schema = $self->result_source->schema;
my $nodes = $self->search(undef, { columns => 'mac' });
if (ref {} eq ref $opts
and exists $opts->{archive} and $opts->{archive}) {
foreach my $set (qw/
NodeIp
NodeNbt
NodeMonitor
Node
/) {
$schema->resultset($set)->search(
{ mac => { '-in' => $nodes->as_query }},
)->update({ active => \'false' });
}
$schema->resultset('NodeWireless')
->search({ mac => { '-in' => $nodes->as_query }})->delete;
# avoid letting DBIC delete nodes
return 0E0;
}
else {
foreach my $set (qw/
NodeIp
NodeNbt
NodeMonitor
NodeWireless
/) {
$schema->resultset($set)->search(
{ mac => { '-in' => $nodes->as_query }},
)->delete;
}
# now let DBIC do its thing
return $self->next::method();
}
}
1;

View File

@@ -59,6 +59,22 @@ foreach my $jobtype (keys %jobs_all, keys %jobs) {
};
}
ajax '/ajax/control/admin/delete' => require_role admin => sub {
send_error('Missing device', 400) unless param('device');
my $device = NetAddr::IP::Lite->new(param('device'));
send_error('Bad device', 400)
if ! $device or $device->addr eq '0.0.0.0';
schema('netdisco')->txn_do(sub {
my $device = schema('netdisco')->resultset('Device')
->search({ip => param('device')});
# will delete everything related too...
$device->delete;
});
};
get '/admin/*' => require_role admin => sub {
my ($tag) = splat;

View File

@@ -56,15 +56,7 @@ ajax '/ajax/control/admin/pseudodevice/add' => require_role admin => sub {
ajax '/ajax/control/admin/pseudodevice/del' => require_role admin => sub {
send_error('Bad Request', 400) unless _sanity_ok();
schema('netdisco')->txn_do(sub {
my $device = schema('netdisco')->resultset('Device')
->find({ip => param('ip')});
$device->ports->delete;
$device->device_ips->delete;
$device->delete;
});
forward '/ajax/control/admin/delete', { device => param('ip') };
};
ajax '/ajax/control/admin/pseudodevice/update' => require_role admin => sub {