Index: trunk/DNSDB.pm
===================================================================
--- trunk/DNSDB.pm	(revision 834)
+++ trunk/DNSDB.pm	(revision 838)
@@ -561,4 +561,46 @@
 
 } # end _updateserial()
+
+
+## DNSDB::_recfilter()
+# Utility sub to construct an SQL fragment for host/value filtering based on a filter argument
+# Deconstructs the argument to apply Postgres CIDR operators or Postgres string-matching operators as appropriate
+# Used by recSearchCount(), recSearch(), getRecList(), and getRecCount()
+# Takes a hash of:
+#   filter - string to create SQL fragment from
+#   sql - reference to SQL string.  SQL fragment will be appended to this string
+#   bindvars - reference to list of DBI bind variable scalars to be fed to DBI on execute
+sub _recfilter {
+  my %args = @_;
+
+  # flag for "was this an IPish filter argument?", since we want to fall through
+  # to the second top-level if() if *any* of the ones in the first block fail
+  my $ipfilt = 0;
+
+  if ($args{filter} =~ /^\s*(<|<=|=|>=|>|<>|<<|<<=|>>|>>=)\s*([\da-fA-F].+)\s*$/) {
+    # filter argument starts with a Postgres CIDR operator, followed by something that could be a CIDR value
+    my $filt_op = $1;
+    my $filt_val = $2;
+    # do we have an IP-ish value?
+    if ($filt_val =~ m,^(?:[\d.]+|[0-9a-f]+)(?:/\d+)?$,) {
+      # now make sure
+      my $tmp = new NetAddr::IP $filt_val;
+      if ($tmp) {
+        ${$args{sql}} .= " AND inetlazy(r.val) $filt_op ?";
+        push @{$args{bindvars}}, $filt_val;
+        $ipfilt = 1;
+      } # really looks like a valid IP/CIDR
+    } # looks IPish
+  } # has CIDR operator
+
+  if (!$ipfilt) {
+    # simple text matching, with a bit of mix-n-match to account for .arpa names
+    ${$args{sql}} .= " AND (r.host ~* ? OR r.val ~* ? OR r.host ~* ? OR r.val ~* ?)";
+    my $tmp = join('.',reverse(split(/\./,$args{filter})));
+    push @{$args{bindvars}}, ($args{filter},$args{filter});
+    push @{$args{bindvars}}, ($tmp, $tmp);
+  }
+
+} # _recfilter
 
 
@@ -4466,28 +4508,5 @@
   # Filtering on host/val (mainly normal record list)
   if ($args{filter}) {
-    # not much use to end users, but internal callers may want more fine-grained restriction on CIDR ranges
-    # we'll only support the value-comparison operators;  bitwise/add/subtract don't make much sense in this context
-    my $ipfilt = 0;
-    if ($args{filter} =~ /^\s*(<|<=|=|>=|>|<>|<<|<<=|>>|>>=)\s*([\da-fA-F].+)\s*$/) {
-      my $filt_op = $1;
-      my $filt_val = $2;
-      # do we have an IP-ish value?
-      if ($filt_val =~ m,^(?:[\d.]+|[0-9a-f]+)(?:/\d+)?$,) {
-        # now make sure
-        my $tmp = new NetAddr::IP $filt_val;
-        if ($tmp) {
-          $sql .= " AND inetlazy(r.val) $filt_op ?";
-          push @bindvars, $filt_val;
-          $ipfilt = 1;
-        } # really looks like a valid IP/CIDR
-      } # looks IPish
-    } # has CIDR operator
-    if (!$ipfilt) {
-      # simple text matching, with a bit of mix-n-match to account for .arpa names
-      $sql .= " AND (r.host ~* ? OR r.val ~* ? OR r.host ~* ? OR r.val ~* ?)";
-      my $tmp = join('.',reverse(split(/\./,$args{filter})));
-      push @bindvars, ($args{filter},$args{filter});
-      push @bindvars, ($tmp, $tmp);
-    }
+    _recfilter(filter => $args{filter}, sql => \$sql, bindvars => \@bindvars);
   }
 
@@ -4563,28 +4582,5 @@
   # Filtering on host/val (mainly normal record list)
   if ($args{filter}) {
-    # not much use to end users, but internal callers may want more fine-grained restriction on CIDR ranges
-    # we'll only support the value-comparison operators;  bitwise/add/subtract don't make much sense in this context
-    my $ipfilt = 0;
-    if ($args{filter} =~ /^\s*(<|<=|=|>=|>|<>|<<|<<=|>>|>>=)\s*([\da-fA-F].+)\s*$/) {
-      my $filt_op = $1;
-      my $filt_val = $2;
-      # do we have an IP-ish value?
-      if ($filt_val =~ m,^(?:[\d.]+|[0-9a-f]+)(?:/\d+)?$,) {
-        # now make sure
-        my $tmp = new NetAddr::IP $filt_val;
-        if ($tmp) {
-          $sql .= " AND inetlazy(r.val) $filt_op ?";
-          push @bindvars, $filt_val;
-          $ipfilt = 1;
-        } # really looks like a valid IP/CIDR
-      } # looks IPish
-    } # has CIDR operator
-    if (!$ipfilt) {
-      # simple text matching, with a bit of mix-n-match to account for .arpa names
-      $sql .= " AND (r.host ~* ? OR r.val ~* ? OR r.host ~* ? OR r.val ~* ?)";
-      my $tmp = join('.',reverse(split(/\./,$args{filter})));
-      push @bindvars, ($args{filter},$args{filter});
-      push @bindvars, ($tmp, $tmp);
-    }
+    _recfilter(filter => $args{filter}, sql => \$sql, bindvars => \@bindvars);
   }
 
@@ -5195,6 +5191,5 @@
 JOIN rectypes t ON r.type = t.val
 LEFT JOIN locations l ON r.location = l.location
-WHERE r.type <> 6 AND (r.host ~* ? OR r.val ~* ?)
-);
+WHERE r.type <> 6);
 
 
@@ -5208,4 +5203,7 @@
 
   my $sql = "SELECT count(*)".$recsearchsqlbase;
+
+  my @bindargs;
+  _recfilter(filter => $args{searchfor}, sql => \$sql, bindvars => \@bindargs);
 
   # Limit scope based on group
@@ -5223,5 +5221,5 @@
   }
 
-  my $count = $dbh->selectrow_array($sql, undef, $args{searchfor}, $args{searchfor});
+  my $count = $dbh->selectrow_array($sql, undef, @bindargs);
   $errstr = $dbh->errstr if !$count;
   return $count;
@@ -5245,4 +5243,7 @@
     r.host, t.name AS rectype, r.val, l.description AS location, r.record_id).
     $recsearchsqlbase;
+
+  my @bindargs;
+  _recfilter(filter => $args{searchfor}, sql => \$sql, bindvars => \@bindargs);
 
   # Limit scope based on group
@@ -5282,5 +5283,5 @@
 
 ##fixme: should probably sent the warning somewhere else
-  my $ret = $dbh->selectall_arrayref($sql, { Slice => {} }, $args{searchfor}, $args{searchfor})
+  my $ret = $dbh->selectall_arrayref($sql, { Slice => {} }, @bindargs)
     or warn $dbh->errstr;
   return $ret;
