class Groonga::Command::Parser
Constants
- VERSION
Public Class Methods
new(options={})
click to toggle source
# File lib/groonga/command/parser.rb, line 120 def initialize(options={}) @need_original_source = options.fetch(:need_original_source, true) reset initialize_hooks end
parse(data, &block)
click to toggle source
parses groonga command or HTTP (starts with “/d/”) command. @overload parse(data)
@!macro [new] parser.parse.argument @param [String] data parsed command. @return [Groonga::Command] Returns {Groonga::Command} including parsed data. @!macro parser.parse.argument
@overload parse(data, &block)
@!macro parser.parse.argument
# File lib/groonga/command/parser.rb, line 42 def parse(data, &block) if block_given? event_parse(data, &block) else stand_alone_parse(data) end end
Private Class Methods
consume_data(parser, data)
click to toggle source
# File lib/groonga/command/parser.rb, line 108 def consume_data(parser, data) if data.respond_to?(:each) data.each do |chunk| parser << chunk end else parser << data end parser.finish end
event_parse(data) { |:on_command, command| ... }
click to toggle source
# File lib/groonga/command/parser.rb, line 51 def event_parse(data) parser = new parser.on_command do |command| yield(:on_command, command) end parser.on_load_start do |command| yield(:on_load_start, command) end parser.on_load_columns do |command, columns| yield(:on_load_columns, command, columns) end parser.on_load_value do |command, value| yield(:on_load_value, command, value) end parser.on_load_complete do |command| yield(:on_load_complete, command) end parser.on_comment do |comment| yield(:on_comment, comment) end consume_data(parser, data) end
stand_alone_parse(data)
click to toggle source
# File lib/groonga/command/parser.rb, line 76 def stand_alone_parse(data) parsed_command = nil parser = new parser.on_command do |command| parsed_command = command end parser.on_load_columns do |command, columns| command[:columns] ||= columns.join(",") end values = [] parser.on_load_value do |_, value| values << value end parser.on_load_complete do |command| parsed_command = command parsed_command[:values] ||= JSON.generate(values) end consume_data(parser, data) if parsed_command.nil? if data.respond_to?(:each) last_chunk = data.last else last_chunk = data end raise Error.new("not completed", last_chunk, "") end parsed_command end
Public Instance Methods
<<(chunk)
click to toggle source
Streaming parsing command. @param [String] chunk parsed chunk of command.
# File lib/groonga/command/parser.rb, line 128 def <<(chunk) @buffer << chunk @buffer.force_encoding("ASCII-8BIT") consume_buffer end
finish()
click to toggle source
Finishes parsing. If Parser
is loading values specified “load” command, this method raises {Parser::Error}.
# File lib/groonga/command/parser.rb, line 136 def finish if @loading original_source = @command.original_source if original_source last_line = original_source.lines.to_a.last else last_line = "" end raise Error.new("not completed", last_line, "") else catch do |tag| parse_line(@buffer) end end end
on_command(*arguments, &block)
click to toggle source
@overload on_command
(command) @overload on_command
{|command| }
# File lib/groonga/command/parser.rb, line 154 def on_command(*arguments, &block) if block_given? @on_command_hook = block else @on_command_hook.call(*arguments) if @on_command_hook end end
on_comment(*arguments, &block)
click to toggle source
@overload on_comment
(comment) @overload on_comment
{|comment| }
# File lib/groonga/command/parser.rb, line 204 def on_comment(*arguments, &block) if block_given? @on_comment_hook = block else @on_comment_hook.call(*arguments) if @on_comment_hook end end
on_load_columns(*arguments, &block)
click to toggle source
@overload on_load_columns
(command) @overload on_load_columns
{|command| }
# File lib/groonga/command/parser.rb, line 174 def on_load_columns(*arguments, &block) if block_given? @on_load_columns_hook = block else @on_load_columns_hook.call(*arguments) if @on_load_columns_hook end end
on_load_complete(*arguments, &block)
click to toggle source
@overload on_load_complete
(command) @overload on_load_complete
(command) { }
# File lib/groonga/command/parser.rb, line 194 def on_load_complete(*arguments, &block) if block_given? @on_load_complete_hook = block else @on_load_complete_hook.call(*arguments) if @on_load_complete_hook end end
on_load_start(*arguments, &block)
click to toggle source
@overload on_load_start
(command) @overload on_load_start
{|command| }
# File lib/groonga/command/parser.rb, line 164 def on_load_start(*arguments, &block) if block_given? @on_load_start_hook = block else @on_load_start_hook.call(*arguments) if @on_load_start_hook end end
on_load_value(*arguments, &block)
click to toggle source
@overload on_load_value
(command) @overload on_load_value
{|command| }
# File lib/groonga/command/parser.rb, line 184 def on_load_value(*arguments, &block) if block_given? @on_load_value_hook = block else @on_load_value_hook.call(*arguments) if @on_load_value_hook end end
Private Instance Methods
consume_buffer()
click to toggle source
# File lib/groonga/command/parser.rb, line 213 def consume_buffer catch do |tag| loop do if @loading consume_load_values(tag) else parse_line(consume_line(tag)) end end end end
consume_line(tag)
click to toggle source
# File lib/groonga/command/parser.rb, line 230 def consume_line(tag) current_line, separator, rest = @buffer.partition(/\r?\n/) throw(tag) if separator.empty? if current_line.end_with?("\\") @buffer.sub!(/\\\r?\n/, "") consume_line(tag) else @buffer = rest current_line end end
consume_load_values(tag)
click to toggle source
# File lib/groonga/command/parser.rb, line 225 def consume_load_values(tag) throw(tag) if @buffer.empty? @load_values_parser << @buffer end
initialize_hooks()
click to toggle source
# File lib/groonga/command/parser.rb, line 352 def initialize_hooks @on_command_hook = nil @on_load_start_hook = nil @on_load_columns_hook = nil @on_load_value_hook = nil @on_load_complete_hook = nil end
initialize_load_values_parser()
click to toggle source
# File lib/groonga/command/parser.rb, line 360 def initialize_load_values_parser @load_values_parser = LoadValuesParser.new @load_values_parser.on_value = lambda do |value| if value.is_a?(::Array) and @command.columns.nil? @command.columns = value on_load_columns(@command, value) else on_load_value(@command, value) end end @load_values_parser.on_consumed = lambda do |consumed| if @loading @command.original_source << consumed if @need_original_source if @buffer.bytesize == consumed.bytesize @buffer = "".force_encoding("ASCII-8BIT") else @buffer = @buffer[consumed.bytesize..-1] end end end @load_values_parser.on_end = lambda do |rest| loading = @loading on_load_complete(@command) reset @buffer << rest if loading and rest end end
parse_command(input)
click to toggle source
# File lib/groonga/command/parser.rb, line 284 def parse_command(input) if input.start_with?("/") parse_uri_path(input) else parse_command_line(input) end end
parse_command_line(command_line)
click to toggle source
# File lib/groonga/command/parser.rb, line 321 def parse_command_line(command_line) splitter = CommandLineSplitter.new(command_line) name, *arguments = splitter.split if name.nil? raise Error.new("invalid command name", command_line, "") end pair_arguments = {} ordered_arguments = [] until arguments.empty? argument = arguments.shift if argument.start_with?("--") pair_arguments[argument.sub(/\A--/, "")] = arguments.shift else ordered_arguments << argument end end command_class = ::Groonga::Command.find(name) command = command_class.new(name, pair_arguments, ordered_arguments) command.original_format = :command command end
parse_line(line)
click to toggle source
# File lib/groonga/command/parser.rb, line 243 def parse_line(line) case line when /\A\s*\z/ # ignore empty line when /\A\#/ on_comment($POSTMATCH) else @command = parse_command(line) return if @command.nil? @command.original_source = line if @need_original_source process_command end end
parse_uri_path(relative_uri)
click to toggle source
# File lib/groonga/command/parser.rb, line 292 def parse_uri_path(relative_uri) path, arguments_string = relative_uri.split(/\?/, 2) arguments = {} if arguments_string arguments_string.split(/&/).each do |argument_string| key, value = argument_string.split(/\=/, 2) next if value.nil? arguments[CGI.unescape(key)] = CGI.unescape(value) end end if /\/([^\/]*)\z/=~ path prefix = $PREMATCH name = $1 else prefix = "" name = path end return nil if name.empty? name, output_type = name.split(/\./, 2) arguments["output_type"] = output_type if output_type command_class = ::Groonga::Command.find(name) command = command_class.new(name, arguments) command.original_format = :uri command.path_prefix = prefix command end
process_command()
click to toggle source
# File lib/groonga/command/parser.rb, line 258 def process_command if @command.command_name == "load" on_load_start(@command) if @command.columns on_load_columns(@command, @command.columns) end if @command[:values] initialize_load_values_parser @load_values_parser << @command[:values] reset else if @command.original_format == :uri on_load_complete(@command) reset else @command.original_source << "\n" if @need_original_source @loading = true initialize_load_values_parser end end else on_command(@command) @command = nil end end
reset()
click to toggle source
# File lib/groonga/command/parser.rb, line 345 def reset @command = nil @loading = false @buffer = "".force_encoding("ASCII-8BIT") @load_values_parser = nil end