[Groonga-commit] ranguba/groonga-client at cac9e12 [master] Merge groonga-client-cli

Back to archive index

Kouhei Sutou null+****@clear*****
Tue Dec 20 15:41:53 JST 2016


Kouhei Sutou	2016-12-20 15:41:53 +0900 (Tue, 20 Dec 2016)

  New Revision: cac9e125272aa8f10044e5eed266f8fe1fa53946
  https://github.com/ranguba/groonga-client/commit/cac9e125272aa8f10044e5eed266f8fe1fa53946

  Message:
    Merge groonga-client-cli
    
    Because groonga-command-parser works on Windows.

  Added files:
    bin/groonga-client
    lib/groonga/client/cli.rb
  Modified files:
    groonga-client.gemspec

  Added: bin/groonga-client (+23 -0) 100755
===================================================================
--- /dev/null
+++ bin/groonga-client    2016-12-20 15:41:53 +0900 (1963f1c)
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+# -*- ruby -*-
+#
+# Copyright (C) 2015-2016  Kouhei Sutou <kou �� clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+require "groonga/client/cli"
+
+cli = Groonga::Client::CLI.new
+exit(cli.run(ARGV))

  Modified: groonga-client.gemspec (+4 -1)
===================================================================
--- groonga-client.gemspec    2016-12-20 14:17:00 +0900 (9612b01)
+++ groonga-client.gemspec    2016-12-20 15:41:53 +0900 (3ddaae7)
@@ -43,9 +43,13 @@ Gem::Specification.new do |spec|
   spec.files += Dir.glob("lib/**/*.rb")
   spec.files += Dir.glob("doc/text/*")
   spec.test_files += Dir.glob("test/**/*")
+  Dir.chdir("bin") do
+    spec.executables = Dir.glob("*")
+  end
 
   spec.add_runtime_dependency("gqtp", ">= 1.0.4")
   spec.add_runtime_dependency("groonga-command", ">= 1.2.8")
+  spec.add_runtime_dependency("groonga-command-parser", ">= 1.1.7")
   spec.add_runtime_dependency("hashie")
 
   spec.add_development_dependency("bundler")
@@ -54,5 +58,4 @@ Gem::Specification.new do |spec|
   spec.add_development_dependency("test-unit-rr")
   spec.add_development_dependency("packnga")
   spec.add_development_dependency("redcarpet")
-  spec.add_development_dependency("groonga-command-parser")
 end

  Added: lib/groonga/client/cli.rb (+233 -0) 100644
===================================================================
--- /dev/null
+++ lib/groonga/client/cli.rb    2016-12-20 15:41:53 +0900 (b958c1f)
@@ -0,0 +1,233 @@
+# Copyright (C) 2015-2016  Kouhei Sutou <kou �� clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+require "ostruct"
+require "optparse"
+require "json"
+require "securerandom"
+
+require "groonga/client"
+
+require "groonga/command/parser"
+
+module Groonga
+  class Client
+    class CLI
+      def initialize
+        @protocol = :http
+        @host     = "localhost"
+        @port     = nil
+
+        @read_timeout = Client::Default::READ_TIMEOUT
+
+        @chunk = false
+
+        @runner_options = {
+          :split_load_chunk_size => 10000,
+          :generate_request_id   => false,
+        }
+      end
+
+      def run(argv)
+        command_file_paths = parse_command_line(argv)
+
+        @client = Client.new(:protocol => @protocol,
+                             :host     => @host,
+                             :port     => @port,
+                             :read_timeout => @read_timeout,
+                             :chunk    => @chunk,
+                             :backend  => :synchronous)
+        runner = Runner.new(@client, @runner_options)
+
+        if command_file_paths.empty?
+          $stdin.each_line do |line|
+            runner << line
+          end
+        else
+          command_file_paths.each do |command_file_path|
+            File.open(command_file_path) do |command_file|
+              last_line = nil
+              command_file.each_line do |line|
+                last_line = line
+                runner << line
+              end
+              if last_line and !last_line.end_with?("\n")
+                runner << "\n"
+              end
+            end
+          end
+        end
+        runner.finish
+
+        true
+      end
+
+      private
+      def parse_command_line(argv)
+        parser = OptionParser.new
+        parser.version = VERSION
+        parser.banner += " GROONGA_COMMAND_FILE1 GROONGA_COMMAND_FILE2 ..."
+
+        parser.separator("")
+
+        parser.separator("Connection:")
+
+        available_protocols = [:http, :gqtp]
+        parser.on("--protocol=PROTOCOL", [:http, :gqtp],
+                  "Protocol to connect to Groonga server.",
+                  "[#{available_protocols.join(", ")}]",
+                  "(#{@protocol})") do |protocol|
+          @protocol = protocol
+        end
+
+        parser.on("--host=HOST",
+                  "Groonga server to be connected.",
+                  "(#{@host})") do |host|
+          @host = host
+        end
+
+        parser.on("--port=PORT", Integer,
+                  "Port number of Groonga server to be connected.",
+                  "(auto)") do |port|
+          @port = port
+        end
+
+        parser.on("--read-timeout=TIMEOUT", Integer,
+                  "Timeout on reading response from Groonga server.",
+                  "You can disable timeout by specifying -1.",
+                  "(#{@read_timeout})") do |timeout|
+          @read_timeout = timeout
+        end
+
+        parser.on("--split-load-chunk-size=SIZE", Integer,
+                  "Split a large load to small loads.",
+                  "Each small load has at most SIZE records.",
+                  "Set 0 to SIZE to disable this feature.",
+                  "(#{@runner_options[:split_load_chunk_size]})") do |size|
+          @runner_options[:split_load_chunk_size] = size
+        end
+
+        parser.on("--[no-]generate-request-id",
+                  "Add auto generated request ID to all commands.",
+                  "(#{@runner_options[:generate_request_id]})") do |boolean|
+          @runner_options[:generate_request_id] = boolean
+        end
+
+        parser.on("--[no-]chunk",
+                  "Use \"Transfer-Encoding: chunked\" for load command.",
+                  "HTTP only.",
+                  "(#{@chunk})") do |boolean|
+          @chunk = boolean
+        end
+
+        command_file_paths = parser.parse(argv)
+
+        @port ||= default_port(@protocol)
+
+        command_file_paths
+      end
+
+      def default_port(protocol)
+        case protocol
+        when :http
+          10041
+        when :gqtp
+          10043
+        end
+      end
+
+      class Runner
+        def initialize(client, options={})
+          @client = client
+          @split_load_chunk_size = options[:split_load_chunk_size] || 10000
+          @generate_request_id   = options[:generate_request_id]
+          @load_values = []
+          @parser = create_command_parser
+        end
+
+        def <<(line)
+          @parser << line
+        end
+
+        def finish
+          @parser.finish
+        end
+
+        private
+        def create_command_parser
+          parser = Groonga::Command::Parser.new
+
+          parser.on_command do |command|
+            run_command(command)
+          end
+
+          parser.on_load_columns do |command, columns|
+            command[:columns] ||= columns.join(",")
+          end
+
+          parser.on_load_value do |command, value|
+            unless command[:values]
+              @load_values << value
+              if @load_values.size == @split_load_chunk_size
+                consume_load_values(command)
+              end
+            end
+            command.original_source.clear
+          end
+
+          parser.on_load_complete do |command|
+            if command[:values]
+              run_command(client, command)
+            else
+              consume_load_values(command)
+            end
+          end
+
+          parser
+        end
+
+        def consume_load_values(load_command)
+          return if @load_values.empty?
+
+          values_json = "["
+          @load_values.each_with_index do |value, i|
+            values_json << "," unless i.zero?
+            values_json << "\n"
+            values_json << JSON.generate(value)
+          end
+          values_json << "\n]\n"
+          load_command[:values] = values_json
+          run_command(load_command)
+          @load_values.clear
+          load_command[:values] = nil
+        end
+
+        def run_command(command)
+          command[:request_id] ||= SecureRandom.uuid if @generate_request_id
+          response =****@clien*****(command)
+          case command.output_type
+          when :json
+            puts(JSON.pretty_generate([response.header, response.body]))
+          when :xml
+            puts(response.raw)
+          else
+            puts(response.body)
+          end
+        end
+      end
+    end
+  end
+end
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index