Class: Sycsvpro::Filter

Inherits:
Object
  • Object
show all
Defined in:
lib/sycsvpro/filter.rb

Overview

Creates a new filter that can be extended by sub-classes. A sub-class needs to override the process method

Direct Known Subclasses

ColumnFilter, Header, RowFilter

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(values, options = {}) ⇒ Filter

Creates a new filter



24
25
26
27
28
29
30
31
32
# File 'lib/sycsvpro/filter.rb', line 24

def initialize(values, options={})
  @date_format = options[:df] || "%Y-%m-%d"
  @filter  = []
  @types   = []
  @pattern = []
  @pivot   = {}
  @boolean_filter = ""
  create_filter(values)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(id, *args, &block) ⇒ Object

Creates the filters based on the given patterns



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/sycsvpro/filter.rb', line 35

def method_missing(id, *args, &block)
  boolean_row_regex = %r{
    BEGIN(\(*[nsd]\d+[<!=~>]{1,2}
     (?:[A-Z][A-Za-z]*\.new\(.*?\)|\d+|['"].*?['"])
     (?:\)*(?:&&|\|\||$)
     \(*[nsd]\d+[<!=~>]{1,2}
     (?:[A-Z][A-Za-z]*\.new\(.*?\)|\d+|['"].*?['"])\)*)*)END
  }xi

  return boolean_row($1, args, block)          if id =~ boolean_row_regex
  return equal($1, args, block)                if id =~ /^(\d+)$/
  return equal_type($1, $2, args, block)       if id =~ /^(s|n|d):(\d+)$/
  return range($1, $2, args, block)            if id =~ /^(\d+)-(\d+)$/
  return range_type($1, $2, $3, args, block)   if id =~ /^(s|n|d):(\d+)-(\d+)$/
  return regex($1, args, block)                if id =~ /^\/(.*)\/$/
  return col_regex($1, $2, args, block)        if id =~ /^(\d+):\/(.*)\/$/
  return date($1, $2, $3, args, block)         if id =~ /^(\d+):(<|=|>)(\d+.\d+.\d+)$/
  return date_range($1, $2, $3, args, block)   if id =~ /^(\d+):(\d+.\d+.\d+.)-(\d+.\d+.\d+)$/
  return number($1, $2, $3, args, block)       if id =~ /^(\d+):(<|=|>)(\d+)$/
  return number_range($1, $2, $3, args, block) if id =~ /^(\d):(\d+)-(\d+)$/

  super
end

Instance Attribute Details

#boolean_filterObject (readonly)

Boolean for rows



15
16
17
# File 'lib/sycsvpro/filter.rb', line 15

def boolean_filter
  @boolean_filter
end

#date_formatObject (readonly)

When date are used as filters the date format has to be provided



11
12
13
# File 'lib/sycsvpro/filter.rb', line 11

def date_format
  @date_format
end

#filterObject (readonly)

Filter for rows and columns



13
14
15
# File 'lib/sycsvpro/filter.rb', line 13

def filter
  @filter
end

#patternObject (readonly)

Pattern that is used as a filter



19
20
21
# File 'lib/sycsvpro/filter.rb', line 19

def pattern
  @pattern
end

#pivotObject (readonly)

Comparison that is used as a filter



21
22
23
# File 'lib/sycsvpro/filter.rb', line 21

def pivot
  @pivot
end

#typesObject (readonly)

Type of column (n = number, s = string)



17
18
19
# File 'lib/sycsvpro/filter.rb', line 17

def types
  @types
end

Instance Method Details

#has_filter?Boolean

Checks whether a filter has been set. Returns true if filter has been set otherwise false

Returns:

  • (Boolean)


112
113
114
# File 'lib/sycsvpro/filter.rb', line 112

def has_filter?
  return !(filter.empty? and pattern.empty? and boolean_filter.empty?)
end

#match_boolean_filter?(values = []) ⇒ Boolean

Checks whether the values match the boolean filter

Returns:

  • (Boolean)


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/sycsvpro/filter.rb', line 65

def match_boolean_filter?(values=[])
  return false if boolean_filter.empty? or values.empty?
  expression = boolean_filter
  columns = expression.scan(/(([nsd])(\d+))([<!=~>]{1,2})(.*?)(?:[\|&]{2}|$)/)
  columns.each do |c|
    value = case c[1]
    when 'n'
      values[c[2].to_i].empty? ? '0' : values[c[2].to_i]
    when 's'
      "\"#{values[c[2].to_i]}\""
    when 'd'
      begin
        Date.strptime(values[c[2].to_i], date_format)
      rescue Exception => e
        case c[3]
        when '<', '<=', '=='
          "#{c[4]}+1"
        when '>', '>='
          '0'
        when '!='
          c[4]
        end
      else
        "Date.strptime('#{values[c[2].to_i]}', '#{date_format}')"
      end 
    end
    expression = expression.gsub(c[0], value)
  end
  eval(expression)
end

#pivot_each_column(values = []) ⇒ Object

Yields the column value and whether the filter matches the column



97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/sycsvpro/filter.rb', line 97

def pivot_each_column(values=[])
  pivot.each do |column, parameters|
    value = values[parameters[:col].to_i]
    value = value.strip.gsub(/^"|"$/, "") unless value.nil?
    match = false
    begin
      match = eval(parameters[:operation].gsub('[value]', value))
    rescue Exception => e

    end
    yield column, match
  end
end

#process(object, options = {}) ⇒ Object

Processes the filter. Needs to be overridden by the sub-class



60
61
62
# File 'lib/sycsvpro/filter.rb', line 60

def process(object, options={})
  raise 'Needs to be overridden by sub class'
end