1package App::Netdisco::DB::ResultSet::NodeNbt;
2use base 'App::Netdisco::DB::ResultSet';
3
4use strict;
5use warnings;
6
7__PACKAGE__->load_components(qw/
8  +App::Netdisco::DB::ExplicitLocking
9/);
10
11my $search_attr = {
12    order_by => {'-desc' => 'time_last'},
13    '+columns' => [
14      'oui.company',
15      { time_first_stamp => \"to_char(time_first, 'YYYY-MM-DD HH24:MI')" },
16      { time_last_stamp =>  \"to_char(time_last, 'YYYY-MM-DD HH24:MI')" },
17    ],
18    join => 'oui'
19};
20
21=head1 with_times
22
23This is a modifier for any C<search()> (including the helpers below) which
24will add the following additional synthesized columns to the result set:
25
26=over 4
27
28=item time_first_stamp
29
30=item time_last_stamp
31
32=back
33
34=cut
35
36sub with_times {
37  my ($rs, $cond, $attrs) = @_;
38
39  return $rs
40    ->search_rs({}, $search_attr)
41    ->search($cond, $attrs);
42}
43
44=head1 search_by_ip( \%cond, \%attrs? )
45
46 my $set = $rs->search_by_ip({ip => '192.0.2.1', active => 1});
47
48Like C<search()>, this returns a ResultSet of matching rows from the
49NodeNbt table.
50
51=over 4
52
53=item *
54
55The C<cond> parameter must be a hashref containing a key C<ip> with the value
56to search for. Value can either be a simple string of IPv4 or IPv6, or a
57L<NetAddr::IP::Lite> object in which case all results within the CIDR/Prefix
58will be retrieved.
59
60=item *
61
62Results are ordered by time last seen.
63
64=item *
65
66Additional columns C<time_first_stamp> and C<time_last_stamp> provide
67preformatted timestamps of the C<time_first> and C<time_last> fields.
68
69=item *
70
71A JOIN is performed on the OUI table and the OUI C<company> column prefetched.
72
73=back
74
75To limit results only to active IPs, set C<< {active => 1} >> in C<cond>.
76
77=cut
78
79sub search_by_ip {
80    my ($rs, $cond, $attrs) = @_;
81
82    die "ip address required for search_by_ip\n"
83      if ref {} ne ref $cond or !exists $cond->{ip};
84
85    # handle either plain text IP or NetAddr::IP (/32 or CIDR)
86    my ($op, $ip) = ('=', delete $cond->{ip});
87
88    if ('NetAddr::IP::Lite' eq ref $ip and $ip->num > 1) {
89        $op = '<<=';
90        $ip = $ip->cidr;
91    }
92    $cond->{ip} = { $op => $ip };
93
94    return $rs
95      ->search_rs({}, $search_attr)
96      ->search($cond, $attrs);
97}
98
99=head1 search_by_name( \%cond, \%attrs? )
100
101 my $set = $rs->search_by_name({nbname => 'MYNAME', active => 1});
102
103Like C<search()>, this returns a ResultSet of matching rows from the
104NodeNbt table.
105
106=over 4
107
108=item *
109
110The C<cond> parameter must be a hashref containing a key C<nbname> with the
111value to search for. The value may optionally include SQL wildcard characters.
112
113=item *
114
115Results are ordered by time last seen.
116
117=item *
118
119Additional columns C<time_first_stamp> and C<time_last_stamp> provide
120preformatted timestamps of the C<time_first> and C<time_last> fields.
121
122=item *
123
124A JOIN is performed on the OUI table and the OUI C<company> column prefetched.
125
126=back
127
128To limit results only to active IPs, set C<< {active => 1} >> in C<cond>.
129
130=cut
131
132sub search_by_name {
133    my ($rs, $cond, $attrs) = @_;
134
135    die "nbname field required for search_by_name\n"
136      if ref {} ne ref $cond or !exists $cond->{nbname};
137
138    $cond->{nbname} = { '-ilike' => delete $cond->{nbname} };
139
140    return $rs
141      ->search_rs({}, $search_attr)
142      ->search($cond, $attrs);
143}
144
145=head1 search_by_mac( \%cond, \%attrs? )
146
147 my $set = $rs->search_by_mac({mac => '00:11:22:33:44:55', active => 1});
148
149Like C<search()>, this returns a ResultSet of matching rows from the
150NodeNbt table.
151
152=over 4
153
154=item *
155
156The C<cond> parameter must be a hashref containing a key C<mac> with the value
157to search for.
158
159=item *
160
161Results are ordered by time last seen.
162
163=item *
164
165Additional columns C<time_first_stamp> and C<time_last_stamp> provide
166preformatted timestamps of the C<time_first> and C<time_last> fields.
167
168=item *
169
170A JOIN is performed on the OUI table and the OUI C<company> column prefetched.
171
172=back
173
174To limit results only to active IPs, set C<< {active => 1} >> in C<cond>.
175
176=cut
177
178sub search_by_mac {
179    my ($rs, $cond, $attrs) = @_;
180
181    die "mac address required for search_by_mac\n"
182      if ref {} ne ref $cond or !exists $cond->{mac};
183
184    return $rs
185      ->search_rs({}, $search_attr)
186      ->search($cond, $attrs);
187}
188
1891;
190