summaryrefslogtreecommitdiff
path: root/lib/MON/Filter.pm
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2015-01-02 14:00:56 +0100
committerPaul Buetow <paul@buetow.org>2015-01-02 14:00:56 +0100
commit4f27f3ea59baa6cfca0ac1df96b1dfedbd83706c (patch)
tree79754e3c49216f80cb3ad5579851fca0bf1a31c9 /lib/MON/Filter.pm
initial
Diffstat (limited to 'lib/MON/Filter.pm')
-rw-r--r--lib/MON/Filter.pm166
1 files changed, 166 insertions, 0 deletions
diff --git a/lib/MON/Filter.pm b/lib/MON/Filter.pm
new file mode 100644
index 0000000..d16d1c5
--- /dev/null
+++ b/lib/MON/Filter.pm
@@ -0,0 +1,166 @@
+package MON::Filter;
+
+use strict;
+use warnings;
+use v5.10;
+use autodie;
+
+use Data::Dumper;
+
+use MON::Display;
+use MON::Config;
+use MON::Utils;
+
+our @ISA = ('MON::Display');
+
+sub new {
+ my ( $class, %opts ) = @_;
+
+ my $self = bless \%opts, $class;
+
+ $self->init();
+
+ return $self;
+}
+
+sub init {
+ my ($self) = @_;
+
+ $self->{query_string} = '';
+ $self->{filters} = {};
+ $self->{num_filters} = 0;
+ $self->{is_computed} = 0;
+ $self->{or} = [];
+
+ return undef;
+}
+
+# Create filters with params
+sub compute {
+ my ( $self, $params ) = @_;
+
+ $self->debug( 'Computing filter using', $params );
+ return undef if $self->{is_computed};
+
+ my %likes;
+
+ if ( defined $params and ref $params eq 'ARRAY' ) {
+ while (@$params) {
+ my $op_token = pop @$params;
+ given ($op_token) {
+ when (/^OP_LIKE$/) {
+ my $arg2 = pop @$params;
+ my $arg1 = pop @$params;
+
+ if ( exists $likes{$arg1} ) {
+ $self->error(
+"Can not run multiple 'like's on '$arg1', since it is used for the API query_string"
+ );
+ }
+ else {
+ $likes{$arg1} = "$arg1=$arg2";
+ }
+
+ }
+ when (/^OP_/) {
+ $self->{filters}{$_} = [] unless exists $self->{filters}{$_};
+ my $arg2 = pop @$params;
+ my $arg1 = pop @$params;
+ push @{ $self->{filters}{$_} }, [ $arg1, $arg2 ];
+ $self->{num_filters}++;
+ }
+ default {
+ $self->error("Inernal error: Operator expected instead of $_");
+ }
+ }
+ }
+ }
+
+ $self->{query_string} = '?' . join( '&', values %likes );
+ $self->{is_computed} = 1;
+
+ $self->debug( 'Computed filter:', $self->{filters} );
+ $self->verbose( "Computed query string is: " . $self->{query_string} );
+
+ return undef;
+}
+
+sub filter {
+ my ( $self, $objects ) = @_;
+
+ my $config = $self->{config};
+ my $json = $self->{json};
+
+ return $objects unless $self->{num_filters};
+
+ my $num = sub {
+ my $str = shift;
+ $str =~ s/\D//g;
+ $str = 0 if $str eq '';
+ return int $str;
+ };
+
+ while ( my ( $op, $vals ) = each %{ $self->{filters} } ) {
+ for my $val (@$vals) {
+ my ( $key, $val ) = @$val;
+
+ @$objects = grep {
+ my $object = $_;
+
+ if ( exists $object->{$key} ) {
+ if ( $op eq 'OP_MATCHES' and $object->{$key} =~ /$val/ ) {
+ 1;
+
+ }
+ elsif ( $op eq 'OP_NMATCHES' and $object->{$key} !~ /$val/ ) {
+ 1;
+
+ }
+ elsif ( $op eq 'OP_EQ' and $object->{$key} eq $val ) {
+ 1;
+
+ }
+ elsif ( $op eq 'OP_NE' and $object->{$key} ne $val ) {
+ 1;
+
+ }
+ elsif ( $op eq 'OP_LT'
+ and $num->( $object->{$key} ) < $num->($val) )
+ {
+ 1;
+
+ }
+ elsif ( $op eq 'OP_LE'
+ and $num->( $object->{$key} ) <= $num->($val) )
+ {
+ 1;
+
+ }
+ elsif ( $op eq 'OP_GT'
+ and $num->( $object->{$key} ) > $num->($val) )
+ {
+ 1;
+
+ }
+ elsif ( $op eq 'OP_GE'
+ and $num->( $object->{$key} ) >= $num->($val) )
+ {
+ 1;
+
+ }
+ else {
+ 0;
+ }
+ }
+ else {
+ 0;
+ }
+ } @$objects;
+ }
+ }
+
+ return $objects;
+}
+
+1;
+