Commit 25f927ae authored by Paul Asmuth's avatar Paul Asmuth
Browse files

better filter parser

parent 41895b20
Loading
Loading
Loading
Loading
+30 −29
Original line number Diff line number Diff line
@@ -73,35 +73,36 @@ private

  def eval_filter(arg)
    arg.gsub!("\\'", "\x7") # FIXPAUL: hack! ;)
    if m = arg.match(/^([a-zA-Z_-]+) *= *'(.*)'$/)
      @filters << [m[1], :equals, m[2]]
    elsif m = arg.match(/^([a-zA-Z_-]+) *= *([0-9]+)$/)
      @filters << [m[1], :equals, m[2].to_i]
    elsif m = arg.match(/^([a-zA-Z_-]+) *= *([0-9]+\.[0-9]+)$/)
      @filters << [m[1], :equals, m[2].to_f]
    elsif m = arg.match(/^([a-zA-Z_-]+) *< *([0-9]+)$/)
      @filters << [m[1], :less_than, m[2].to_i]
    elsif m = arg.match(/^([a-zA-Z_-]+) *< *([0-9]+\.[0-9]+)$/)
      @filters << [m[1], :less_than, m[2].to_f]
    elsif m = arg.match(/^([a-zA-Z_-]+) *> *([0-9]+)$/)
      @filters << [m[1], :greater_than, m[2].to_i]
    elsif m = arg.match(/^([a-zA-Z_-]+) *> *([0-9]+\.[0-9]+)$/)
      @filters << [m[1], :greater_than, m[2].to_f]
    elsif m = arg.match(/^([a-zA-Z_-]+) *~ *([0-9]+)-([0-9]+)$/)
      @filters << [m[1], :range_include, (m[2].to_i..m[3].to_i)]
    elsif m = arg.match(/^([a-zA-Z_-]+) *~ *([0-9]+\.[0-9]+)-([0-9]+\.[0-9]+)$/)
      @filters << [m[1], :range_include, (m[2].to_f..m[3].to_f)]
    elsif m = arg.match(/^([a-zA-Z_-]+) *& *(([0-9]+),)+([0-9]+)$/)
      @filters << [m[1], :list_include, m[2..-1].map(&:to_i)]
    elsif m = arg.match(/^([a-zA-Z_-]+) *& *(([0-9]+\.[0-9]+),)+([0-9]+\.[0-9]+)$/)
      @filters << [m[1], :list_include, m[2..-1].map(&:to_f)]
    elsif m = arg.match(/^([a-zA-Z_-]+) *& *('[^']*',)+'[^']*'$/)
      lst = arg.match(/^([a-zA-Z_-]+) *& *(.*)/)[2].scan(/'([^']*)',?/).map do |x|
    key_regex = "([^ ]+)"
    if m = arg.match(/^#{key_regex} *= *'([^']*)'$/)
      @filters << [m[1].gsub("\x7", "'"), :equals, m[2]]
    elsif m = arg.match(/^#{key_regex} *= *([0-9]+)$/)
      @filters << [m[1].gsub("\x7", "'"), :equals, m[2].to_i]
    elsif m = arg.match(/^#{key_regex} *= *([0-9]+\.[0-9]+)$/)
      @filters << [m[1].gsub("\x7", "'"), :equals, m[2].to_f]
    elsif m = arg.match(/^#{key_regex} *< *([0-9]+)$/)
      @filters << [m[1].gsub("\x7", "'"), :less_than, m[2].to_i]
    elsif m = arg.match(/^#{key_regex} *< *([0-9]+\.[0-9]+)$/)
      @filters << [m[1].gsub("\x7", "'"), :less_than, m[2].to_f]
    elsif m = arg.match(/^#{key_regex} *> *([0-9]+)$/)
      @filters << [m[1].gsub("\x7", "'"), :greater_than, m[2].to_i]
    elsif m = arg.match(/^#{key_regex} *> *([0-9]+\.[0-9]+)$/)
      @filters << [m[1].gsub("\x7", "'"), :greater_than, m[2].to_f]
    elsif m = arg.match(/^#{key_regex} *~ *([0-9]+)-([0-9]+)$/)
      @filters << [m[1].gsub("\x7", "'"), :range_include, (m[2].to_i..m[3].to_i)]
    elsif m = arg.match(/^#{key_regex} *~ *([0-9]+\.[0-9]+)-([0-9]+\.[0-9]+)$/)
      @filters << [m[1].gsub("\x7", "'"), :range_include, (m[2].to_f..m[3].to_f)]
    elsif m = arg.match(/^#{key_regex} *& *(([0-9]+),)+([0-9]+)$/)
      @filters << [m[1].gsub("\x7", "'"), :list_include, m[2..-1].map(&:to_i)]
    elsif m = arg.match(/^#{key_regex} *& *(([0-9]+\.[0-9]+),)+([0-9]+\.[0-9]+)$/)
      @filters << [m[1].gsub("\x7", "'"), :list_include, m[2..-1].map(&:to_f)]
    elsif m = arg.match(/^#{key_regex} *& *('[^']*',)+'[^']*'$/)
      @filters << [m[1].gsub("\x7", "'"), :list_include, arg
        .match(/^#{key_regex} *& *(.*)/)[2].scan(/'([^']*)',?/).map do |x|
          x.first.gsub("\x7", "'")
      end
      @filters << [m[1], :list_include, lst.to_a]
    elsif m = arg.match(/^([a-zA-Z_-]+)$/)
      @filters << [m[1], :exists, nil]
      end.to_a]
    elsif m = arg.match(/^#{key_regex}$/)
      @filters << [m[1].gsub("\x7", "'"), :exists, nil]
    else
      raise InvalidQueryError.new("invalid filter: filter(#{arg})")
    end