150 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| package App::Netdisco::DB::ResultSet::Node;
 | |
| use base 'App::Netdisco::DB::ResultSet';
 | |
| 
 | |
| use strict;
 | |
| use warnings;
 | |
| 
 | |
| __PACKAGE__->load_components(qw/
 | |
|   +App::Netdisco::DB::ExplicitLocking
 | |
| /);
 | |
| 
 | |
| =head1 ADDITIONAL METHODS
 | |
| 
 | |
| =head2 search_by_mac( \%cond, \%attrs? )
 | |
| 
 | |
|  my $set = $rs->search_by_mac({mac => '00:11:22:33:44:55', active => 1});
 | |
| 
 | |
| Like C<search()>, this returns a ResultSet of matching rows from the Node
 | |
| table.
 | |
| 
 | |
| =over 4
 | |
| 
 | |
| =item *
 | |
| 
 | |
| The C<cond> parameter must be a hashref containing a key C<mac> with
 | |
| the value to search for.
 | |
| 
 | |
| =item *
 | |
| 
 | |
| Results are ordered by time last seen.
 | |
| 
 | |
| =item *
 | |
| 
 | |
| Additional columns C<time_first_stamp> and C<time_last_stamp> provide
 | |
| preformatted timestamps of the C<time_first> and C<time_last> fields.
 | |
| 
 | |
| =item *
 | |
| 
 | |
| A JOIN is performed on the Device table and the Device C<dns> column
 | |
| prefetched.
 | |
| 
 | |
| =back
 | |
| 
 | |
| To limit results only to active nodes, set C<< {active => 1} >> in C<cond>.
 | |
| 
 | |
| =cut
 | |
| 
 | |
| sub search_by_mac {
 | |
|     my ($rs, $cond, $attrs) = @_;
 | |
| 
 | |
|     die "mac address required for search_by_mac\n"
 | |
|       if ref {} ne ref $cond or !exists $cond->{mac};
 | |
| 
 | |
|     $cond->{'me.mac'} = delete $cond->{mac};
 | |
| 
 | |
|     return $rs
 | |
|       ->search_rs({}, {
 | |
|         order_by => {'-desc' => 'time_last'},
 | |
|         '+columns' => [
 | |
|           'device.dns',
 | |
|           { time_first_stamp => \"to_char(time_first, 'YYYY-MM-DD HH24:MI')" },
 | |
|           { time_last_stamp =>  \"to_char(time_last, 'YYYY-MM-DD HH24:MI')" },
 | |
|         ],
 | |
|         join => 'device',
 | |
|       })
 | |
|       ->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) = @_;
 | |
|   $opts = {} if (ref {} ne ref $opts);
 | |
| 
 | |
|   my $schema = $self->result_source->schema;
 | |
|   my $nodes = $self->search(undef, { columns => 'mac' });
 | |
| 
 | |
|   if (exists $opts->{archive_nodes} and $opts->{archive_nodes}) {
 | |
|       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;
 | |
|   }
 | |
|   elsif (exists $opts->{only_nodes} and $opts->{only_nodes}) {
 | |
|       # now let DBIC do its thing
 | |
|       return $self->next::method();
 | |
|   }
 | |
|   elsif (exists $opts->{keep_nodes} and $opts->{keep_nodes}) {
 | |
|       # avoid letting DBIC delete nodes
 | |
|       return 0E0;
 | |
|   }
 | |
|   else {
 | |
|       # for node_ip and node_nbt *only* delete if there are no longer
 | |
|       # any active nodes referencing the IP or NBT (hence 2nd IN clause).
 | |
|       foreach my $set (qw/
 | |
|         NodeIp
 | |
|         NodeNbt
 | |
|       /) {
 | |
|         $schema->resultset($set)->search({
 | |
|           'me.mac' => { '-in' => $schema->resultset($set)->search({
 | |
|               '-and' => [
 | |
|                 -bool => 'nodes.active',
 | |
|                 'me.mac' => { '-in' => $nodes->as_query }
 | |
|               ]
 | |
|             },
 | |
|             {
 | |
|               columns => 'mac',
 | |
|               join => 'nodes',
 | |
|               group_by => 'me.mac',
 | |
|               having => \[ 'count(nodes.mac) = 0' ],
 | |
|             })->as_query,
 | |
|           },
 | |
|         })->delete;
 | |
|       }
 | |
| 
 | |
|       foreach my $set (qw/
 | |
|         NodeMonitor
 | |
|         NodeWireless
 | |
|       /) {
 | |
|           $schema->resultset($set)->search(
 | |
|             { mac => { '-in' => $nodes->as_query }},
 | |
|           )->delete;
 | |
|       }
 | |
| 
 | |
|       # now let DBIC do its thing
 | |
|       return $self->next::method();
 | |
|   }
 | |
| }
 | |
| 
 | |
| 1;
 |