class Fluent::PluginHelper::RecordAccessor::Accessor

Attributes

keys[R]

Public Class Methods

new(param) click to toggle source
# File lib/fluent/plugin_helper/record_accessor.rb, line 37
def initialize(param)
  @keys = Accessor.parse_parameter(param)

  if @keys.is_a?(Array)
    @last_key = @keys.last
    @dig_keys = @keys[0..-2]
    if @dig_keys.empty?
      @keys = @keys.first
      mcall = method(:call_index)
      mdelete = method(:delete_top)
    else
      mcall = method(:call_dig)
      mdelete = method(:delete_nest)
    end
  else
    # Call [] for single key to reduce dig overhead
    mcall = method(:call_index)
    mdelete = method(:delete_top)
  end

  singleton_class.module_eval do
    define_method(:call, mcall)
    define_method(:delete, mdelete)
  end
end
parse_bracket_notation(param) click to toggle source
# File lib/fluent/plugin_helper/record_accessor.rb, line 165
def self.parse_bracket_notation(param)
  orig_param = param
  result = []
  param = param[1..-1]
  in_bracket = false

  until param.empty?
    if in_bracket
      if param[0] == "'" || param[0] == '"'
        if i = param.index("']") || param.index('"]')
          raise Fluent::ConfigError, "Mismatched quotes. Invalid syntax: #{orig_param}" unless param[0] == param[i]
          result << param[1..i - 1]
          param = param[i + 2..-1]
          in_bracket = false
        else
          raise Fluent::ConfigError, "Incomplete bracket. Invalid syntax: #{orig_param}"
        end
      else
        if i = param.index(']')
          index_value = param[0..i - 1]
          raise Fluent::ConfigError, "missing array index in '[]'. Invalid syntax: #{param}" if index_value == ']'
          result << Integer(index_value)
          param = param[i + 1..-1]
          in_bracket = false
        else
          raise Fluent::ConfigError, "'[' found but ']' not found. Invalid syntax: #{orig_param}"
        end
      end
    else
      if i = param.index('[')
        param = param[i + 1..-1]
        in_bracket = true
      else
        raise Fluent::ConfigError, "found more characters after ']'. Invalid syntax: #{orig_param}"
      end
    end
  end

  raise Fluent::ConfigError, "empty keys in bracket notation" if result.empty?

  result
end
parse_dot_array_op(key, param) click to toggle source
# File lib/fluent/plugin_helper/record_accessor.rb, line 131
def self.parse_dot_array_op(key, param)
  start = key.index('[')
  result = if start.zero?
             []
           else
             [key[0..start - 1]]
           end
  key = key[start + 1..-1]
  in_bracket = true

  until key.empty?
    if in_bracket
      if i = key.index(']')
        index_value = key[0..i - 1]
        raise Fluent::ConfigError, "missing array index in '[]'. Invalid syntax: #{param}" if index_value == ']'
        result << Integer(index_value)
        key = key[i + 1..-1]
        in_bracket = false
      else
        raise Fluent::ConfigError, "'[' found but ']' not found. Invalid syntax: #{param}"
      end
    else
      if i = key.index('[')
        key = key[i + 1..-1]
        in_bracket = true
      else
        raise Fluent::ConfigError, "found more characters after ']'. Invalid syntax: #{param}"
      end
    end
  end

  result
end
parse_dot_notation(param) click to toggle source
# File lib/fluent/plugin_helper/record_accessor.rb, line 105
def self.parse_dot_notation(param)
  result = []
  keys = param[2..-1].split('.')
  keys.each { |key|
    if key.include?('[')
      result.concat(parse_dot_array_op(key, param))
    else
      result << key
    end
  }

  raise Fluent::ConfigError, "empty keys in dot notation" if result.empty?
  validate_dot_keys(result)

  result
end
parse_parameter(param) click to toggle source
# File lib/fluent/plugin_helper/record_accessor.rb, line 95
def self.parse_parameter(param)
  if param.start_with?('$.')
    parse_dot_notation(param)
  elsif param.start_with?('$[')
    parse_bracket_notation(param)
  else
    param
  end
end
validate_dot_keys(keys) click to toggle source
# File lib/fluent/plugin_helper/record_accessor.rb, line 122
def self.validate_dot_keys(keys)
  keys.each { |key|
    next unless key.is_a?(String)
    if /\s+/.match(key)
      raise Fluent::ConfigError, "whitespace character is not allowed in dot notation. Use bracket notation: #{key}"
    end
  }
end

Public Instance Methods

call(r) click to toggle source
# File lib/fluent/plugin_helper/record_accessor.rb, line 63
def call(r)
end
call_dig(r) click to toggle source

To optimize the performance, use class_eval with pre-expanding @keys See gist.github.com/repeatedly/ab553ed260cd080bd01ec71da9427312

# File lib/fluent/plugin_helper/record_accessor.rb, line 68
def call_dig(r)
  r.dig(*@keys)
end
call_index(r) click to toggle source
# File lib/fluent/plugin_helper/record_accessor.rb, line 72
def call_index(r)
  r[@keys]
end
delete(r) click to toggle source
# File lib/fluent/plugin_helper/record_accessor.rb, line 76
def delete(r)
end
delete_nest(r) click to toggle source
# File lib/fluent/plugin_helper/record_accessor.rb, line 79
def delete_nest(r)
  if target = r.dig(*@dig_keys)
    if target.is_a?(Array)
      target.delete_at(@last_key)
    else
      target.delete(@last_key)
    end
  end
rescue
  nil
end
delete_top(r) click to toggle source
# File lib/fluent/plugin_helper/record_accessor.rb, line 91
def delete_top(r)
  r.delete(@keys)
end