class GroongaQueryLog::FilterRewriter

Public Class Methods

new(filter, options={}) click to toggle source
# File lib/groonga-query-log/filter-rewriter.rb, line 20
def initialize(filter, options={})
  @filter = filter
  @options = options
  @vector_accessors = @options[:vector_accessors] || []
  @nullable_reference_number_accessors =
    @options[:nullable_reference_number_accessors] || []
end

Public Instance Methods

rewrite() click to toggle source
# File lib/groonga-query-log/filter-rewriter.rb, line 28
def rewrite
  rewritten = @filter
  if @options[:rewrite_vector_equal]
    rewritten = rewrite_vector_equal(rewritten)
  end
  if @options[:rewrite_vector_not_equal_empty_string]
    rewritten = rewrite_vector_not_equal_empty_string(rewritten)
  end
  if @options[:rewrite_nullable_reference_number]
    rewritten = rewrite_nullable_reference_number(rewritten)
  end
  if @options[:rewrite_not_or_regular_expression]
    rewritten = rewrite_not_or_regular_expression(rewritten)
  end
  if @options[:rewrite_and_not_operator]
    rewritten = rewrite_and_not_operator(rewritten)
  end
  rewritten
end

Private Instance Methods

rewrite_and_not_operator(filter) click to toggle source
# File lib/groonga-query-log/filter-rewriter.rb, line 108
def rewrite_and_not_operator(filter)
  filter.gsub(/&& *!/, "&!")
end
rewrite_not_or_regular_expression(filter) click to toggle source
# File lib/groonga-query-log/filter-rewriter.rb, line 88
def rewrite_not_or_regular_expression(filter)
  filter.gsub(/&& *(?<target_column>[a-zA-Z0-9_.]+) *@~ *"(?<pattern>.*?)"/) do |matched|
    target_column = $LAST_MATCH_INFO[:target_column]
    pattern = $LAST_MATCH_INFO[:pattern]

    case pattern
    when /\A(?<header>(?:\^|\\A)\(\?\!\.\*)
            (?<body>.+)
            (?<footer>\)\.[+*](?:\$|\\z))\z/x
      body = $LAST_MATCH_INFO[:body]
      conditions = body.split("|").collect do |word|
        "&! #{target_column} @ \"#{word.strip}\""
      end
      conditions.join(" ")
    else
      matched
    end
  end
end
rewrite_nullable_reference_number(filter) click to toggle source
# File lib/groonga-query-log/filter-rewriter.rb, line 76
def rewrite_nullable_reference_number(filter)
  filter.gsub(/([a-zA-Z0-9_.]+)/) do |matched|
    accessor = $1
    if @nullable_reference_number_accessors.include?(accessor)
      sub_accessor = accessor.split(".")[0..-2].join(".")
      "(#{sub_accessor}._key == \"\" ? 0 : #{accessor})"
    else
      matched
    end
  end
end
rewrite_vector_equal(filter) click to toggle source
# File lib/groonga-query-log/filter-rewriter.rb, line 49
def rewrite_vector_equal(filter)
  filter.gsub(/([a-zA-Z0-9_.]+) *==/) do |matched|
    variable = $1
    if @vector_accessors.include?(variable)
      "#{variable} @"
    else
      matched
    end
  end
end
rewrite_vector_not_equal_empty_string(filter) click to toggle source
# File lib/groonga-query-log/filter-rewriter.rb, line 60
def rewrite_vector_not_equal_empty_string(filter)
  filter.gsub(/([a-zA-Z0-9_.]+) *!= *(?:''|"")/) do |matched|
    variable = $1
    path = variable.split(".")
    replaced = matched
    path.size.downto(1) do |i|
      sub_path = path[0, i].join(".")
      if @vector_accessors.include?(sub_path)
        replaced = "vector_size(#{sub_path}) > 0"
        break
      end
    end
    replaced
  end
end