Partial search on Device Port MAC address

Implement sql_match helper func for wildcard translation.
This commit is contained in:
Oliver Gorwits
2014-03-02 19:09:31 +00:00
parent 16643045ce
commit 80ffbd5963
5 changed files with 56 additions and 9 deletions

View File

@@ -1,3 +1,9 @@
2.024003_001 - 2014-03-02
[ENHANCEMENTS]
* Partial search on Device Port MAC address
2.024003 - 2014-02-27
[BUG FIXES]

View File

@@ -8,7 +8,7 @@ use Time::Piece;
use Time::Seconds;
our @EXPORT = ();
our @EXPORT_OK = qw/
sort_port sort_modules interval_to_daterange
sort_port sort_modules interval_to_daterange sql_match
/;
our %EXPORT_TAGS = (all => \@EXPORT_OK);
@@ -25,6 +25,35 @@ subroutines.
=head1 EXPORT_OK
=head2 sql_match( $value, $exact? )
Convert wildcard characters "C<*>" and "C<?>" to "C<%>" and "C<_>"
respectively.
Pass a true value to C<$exact> to only substitute the existing wildcards, and
not also add "C<*>" to each end of the value.
In list context, returns two values, the translated value, and also an
L<SQL::Abstract> LIKE clause.
=cut
sub sql_match {
my ($text, $exact) = @_;
return unless $text;
$text =~ s/^\s+//;
$text =~ s/\s+$//;
$text =~ s/[*]+/%/g;
$text =~ s/[?]/_/g;
$text = '%'. $text . '%' unless $exact;
$text =~ s/\%+/%/g;
return ( wantarray ? ($text, {-ilike => $text}) : $text );
}
=head2 sort_port( $a, $b )
Sort port names of various types used by device vendors. Interface is as

View File

@@ -5,6 +5,7 @@ use Dancer::Plugin::DBIC;
use Dancer::Plugin::Auth::Extensible;
use App::Netdisco::Web::Plugin;
use App::Netdisco::Util::Web 'sql_match';
register_search_tab({ tag => 'port', label => 'Port', provides_csv => 1 });
@@ -19,13 +20,14 @@ get '/ajax/content/search/port' => require_login sub {
->search({vlan => $q});
}
else {
my $query = $q;
if (param('partial')) {
$q = "\%$q\%" if $q !~ m/%/;
$query = { -ilike => $q };
}
my ($likeval, $likeclause) = sql_match($q);
$set = schema('netdisco')->resultset('DevicePort')
->search({name => $query});
->search({-or => [
{name => (param('partial') ? $likeclause : $q)},
(length $q == 17 ? {mac => $q}
: \['mac::text ILIKE ?', $likeval]),
]});
}
return unless $set->count;

View File

@@ -5,6 +5,8 @@ use Dancer::Plugin::Ajax;
use Dancer::Plugin::DBIC;
use Dancer::Plugin::Auth::Extensible;
use App::Netdisco::Util::Web 'sql_match';
hook 'before' => sub {
# view settings for node options
var('node_options' => [
@@ -75,6 +77,7 @@ get '/search' => require_login sub {
}
else {
my $nd = $s->resultset('Device')->search_fuzzy($q);
my ($likeval, $likeclause) = sql_match($q);
if ($nd and $nd->count) {
if ($nd->count == 1) {
@@ -90,7 +93,14 @@ get '/search' => require_login sub {
params->{'tab'} = 'device';
}
elsif ($s->resultset('DevicePort')
->search({name => "\%$q\%"})->count) {
->search({
-or => [
{name => $likeclause},
(length $q == 17 ? {mac => $q}
: \['mac::text ILIKE ?', $likeval]),
],
})->count) {
params->{'tab'} = 'port';
}
}

View File

@@ -7,7 +7,7 @@
name="partial"[% ' checked="checked"' IF params.partial %]/>
</label>
<label class="nd_checkboxlabel" for="port_partial">
<span class="nd_searchcheckbox uneditable-input">Partial Name</span>
<span class="nd_searchcheckbox uneditable-input">Partial Match</span>
</label>
</div>
<button id="[% tab.tag %]_submit" type="submit" class="btn btn-info">