groonga-client 0.5.4 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,26 +14,19 @@
14
14
  # License along with this library; if not, write to the Free Software
15
15
  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
- require "optparse"
18
17
  require "json"
19
18
  require "securerandom"
20
19
 
21
- require "groonga/client"
22
-
23
20
  require "groonga/command/parser"
24
21
 
22
+ require "groonga/client"
23
+ require "groonga/client/command-line/parser"
24
+
25
25
  module Groonga
26
26
  class Client
27
27
  module CommandLine
28
28
  class GroongaClient
29
29
  def initialize
30
- @url = nil
31
- @protocol = :http
32
- @host = "localhost"
33
- @port = nil
34
-
35
- @read_timeout = Client::Default::READ_TIMEOUT
36
-
37
30
  @chunk = false
38
31
 
39
32
  @runner_options = {
@@ -42,16 +35,13 @@ module Groonga
42
35
  }
43
36
  end
44
37
 
45
- def run(argv)
46
- command_file_paths = parse_command_line(argv)
38
+ def run(arguments)
39
+ parser = Parser.new
40
+ command_file_paths = parser.parse(arguments) do |option_parser|
41
+ parse_command_line(option_parser)
42
+ end
47
43
 
48
- Client.open(:url => @url,
49
- :protocol => @protocol,
50
- :host => @host,
51
- :port => @port,
52
- :read_timeout => @read_timeout,
53
- :chunk => @chunk,
54
- :backend => :synchronous) do |client|
44
+ parser.open_client(:chunk => @chunk) do |client|
55
45
  runner = Runner.new(client, @runner_options)
56
46
 
57
47
  if command_file_paths.empty?
@@ -79,48 +69,11 @@ module Groonga
79
69
  end
80
70
 
81
71
  private
82
- def parse_command_line(argv)
83
- parser = OptionParser.new
84
- parser.version = VERSION
72
+ def parse_command_line(parser)
85
73
  parser.banner += " GROONGA_COMMAND_FILE1 GROONGA_COMMAND_FILE2 ..."
86
74
 
87
75
  parser.separator("")
88
-
89
- parser.separator("Connection:")
90
-
91
- parser.on("--url=URL",
92
- "URL to connect to Groonga server.",
93
- "If this option is specified,",
94
- "--protocol, --host and --port are ignored.") do |url|
95
- @url = url
96
- end
97
-
98
- available_protocols = [:http, :gqtp]
99
- parser.on("--protocol=PROTOCOL", [:http, :gqtp],
100
- "Protocol to connect to Groonga server.",
101
- "[#{available_protocols.join(", ")}]",
102
- "(#{@protocol})") do |protocol|
103
- @protocol = protocol
104
- end
105
-
106
- parser.on("--host=HOST",
107
- "Groonga server to be connected.",
108
- "(#{@host})") do |host|
109
- @host = host
110
- end
111
-
112
- parser.on("--port=PORT", Integer,
113
- "Port number of Groonga server to be connected.",
114
- "(auto)") do |port|
115
- @port = port
116
- end
117
-
118
- parser.on("--read-timeout=TIMEOUT", Integer,
119
- "Timeout on reading response from Groonga server.",
120
- "You can disable timeout by specifying -1.",
121
- "(#{@read_timeout})") do |timeout|
122
- @read_timeout = timeout
123
- end
76
+ parser.separator("Request:")
124
77
 
125
78
  parser.on("--split-load-chunk-size=SIZE", Integer,
126
79
  "Split a large load to small loads.",
@@ -142,21 +95,6 @@ module Groonga
142
95
  "(#{@chunk})") do |boolean|
143
96
  @chunk = boolean
144
97
  end
145
-
146
- command_file_paths = parser.parse(argv)
147
-
148
- @port ||= default_port(@protocol)
149
-
150
- command_file_paths
151
- end
152
-
153
- def default_port(protocol)
154
- case protocol
155
- when :http
156
- 10041
157
- when :gqtp
158
- 10043
159
- end
160
98
  end
161
99
 
162
100
  class Runner
@@ -0,0 +1,111 @@
1
+ # Copyright (C) 2015-2017 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License as published by the Free Software Foundation; either
6
+ # version 2.1 of the License, or (at your option) any later version.
7
+ #
8
+ # This library is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this library; if not, write to the Free Software
15
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
+
17
+ require "optparse"
18
+
19
+ require "groonga/client"
20
+
21
+ module Groonga
22
+ class Client
23
+ module CommandLine
24
+ class Parser
25
+ def initialize(options={})
26
+ @url = nil
27
+ @protocol = :http
28
+ @host = "localhost"
29
+ @port = nil
30
+
31
+ @read_timeout = options[:read_timeout] || Client::Default::READ_TIMEOUT
32
+ end
33
+
34
+ def parse(arguments)
35
+ parser = OptionParser.new
36
+ parser.version = VERSION
37
+
38
+ parser.separator("")
39
+
40
+ parser.separator("Connection:")
41
+
42
+ parser.on("--url=URL",
43
+ "URL to connect to Groonga server.",
44
+ "If this option is specified,",
45
+ "--protocol, --host and --port are ignored.") do |url|
46
+ @url = url
47
+ end
48
+
49
+ available_protocols = [:http, :gqtp]
50
+ parser.on("--protocol=PROTOCOL", [:http, :gqtp],
51
+ "Protocol to connect to Groonga server.",
52
+ "[#{available_protocols.join(", ")}]",
53
+ "(#{@protocol})") do |protocol|
54
+ @protocol = protocol
55
+ end
56
+
57
+ parser.on("--host=HOST",
58
+ "Groonga server to be connected.",
59
+ "(#{@host})") do |host|
60
+ @host = host
61
+ end
62
+
63
+ parser.on("--port=PORT", Integer,
64
+ "Port number of Groonga server to be connected.",
65
+ "(auto)") do |port|
66
+ @port = port
67
+ end
68
+
69
+ parser.on("--read-timeout=TIMEOUT", Integer,
70
+ "Timeout on reading response from Groonga server.",
71
+ "You can disable timeout by specifying -1.",
72
+ "(#{@read_timeout})") do |timeout|
73
+ @read_timeout = timeout
74
+ end
75
+
76
+ yield(parser)
77
+
78
+ rest = parser.parse(arguments)
79
+
80
+ @port ||= default_port(@protocol)
81
+
82
+ rest
83
+ end
84
+
85
+ def open_client(options={})
86
+ default_options = {
87
+ :url => @url,
88
+ :protocol => @protocol,
89
+ :host => @host,
90
+ :port => @port,
91
+ :read_timeout => @read_timeout,
92
+ :backend => :synchronous,
93
+ }
94
+ Client.open(default_options.merge(options)) do |client|
95
+ yield(client)
96
+ end
97
+ end
98
+
99
+ private
100
+ def default_port(protocol)
101
+ case protocol
102
+ when :http
103
+ 10041
104
+ when :gqtp
105
+ 10043
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,122 @@
1
+ # Copyright (C) 2017 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License as published by the Free Software Foundation; either
6
+ # version 2.1 of the License, or (at your option) any later version.
7
+ #
8
+ # This library is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this library; if not, write to the Free Software
15
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
+
17
+ module Groonga
18
+ class Client
19
+ module CommandLine
20
+ class Runner
21
+ def initialize(client)
22
+ @client = client
23
+ end
24
+
25
+ def run(&block)
26
+ catch do |tag|
27
+ @abort_tag = tag
28
+ run_internal(&block)
29
+ end
30
+ end
31
+
32
+ private
33
+ def abort_run(message)
34
+ $stderr.puts(message)
35
+ throw(@abort_tag, false)
36
+ end
37
+
38
+ def execute_command(name, arguments={})
39
+ response = @client.execute(name, arguments)
40
+ unless response.success?
41
+ abort_run("Failed to run #{name}: #{response.inspect}")
42
+ end
43
+ response
44
+ end
45
+
46
+ def config_get(key)
47
+ execute_command(:config_get, :key => key).body
48
+ end
49
+
50
+ def config_set(key, value)
51
+ execute_command(:config_set, :key => key, :value => value).body
52
+ end
53
+
54
+ def object_exist?(name)
55
+ execute_command(:object_exist, :name => name).body
56
+ end
57
+
58
+ def table_list
59
+ execute_command(:table_list)
60
+ end
61
+
62
+ def column_list(table)
63
+ execute_command(:column_list, :table => table)
64
+ end
65
+
66
+ def column_create(table_name, name, flags, type, source)
67
+ execute_command(:column_create,
68
+ :table => table_name,
69
+ :name => name,
70
+ :flags => flags,
71
+ :type => type,
72
+ :source => source).body
73
+ end
74
+
75
+ def column_create_similar(table_name, column_name, base_column_name)
76
+ if object_exist?(:schema)
77
+ info = execute_command(:schema)["#{table_name}.#{base_column_name}"]
78
+ arguments = info.command.arguments.merge("name" => column_name)
79
+ execute_command(:column_create, arguments).body
80
+ else
81
+ base_column = column_list(table_name).find do |column|
82
+ column.name == base_column_name
83
+ end
84
+ range = base_column.range
85
+ source_columns = base_column.sources.collect do |source|
86
+ if source.include?(".")
87
+ source.split(".", 2)[1]
88
+ else
89
+ "_key"
90
+ end
91
+ end
92
+ flags = base_column.flags.dup
93
+ flags.delete("PERSISTENT")
94
+ column_create(table_name,
95
+ column_name,
96
+ flags.join("|"),
97
+ range,
98
+ source_columns.join(","))
99
+ end
100
+ end
101
+
102
+ def column_remove(table, column)
103
+ execute_command(:column_remove,
104
+ :table => table,
105
+ :name => column).body
106
+ end
107
+
108
+ def column_rename(table, name, new_name)
109
+ execute_command(:column_rename,
110
+ :table => table,
111
+ :name => name,
112
+ :new_name => new_name).body
113
+ end
114
+
115
+ def select(table, arguments={})
116
+ execute_command(:select,
117
+ arguments.merge(:table => table))
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -27,6 +27,27 @@ module Groonga
27
27
  module Protocol
28
28
  class HTTP
29
29
  class Synchronous
30
+ # TODO: Workaround to disable retry in net/http.
31
+ class HTTPClient < Net::HTTP
32
+ class ReadTimeout < StandardError
33
+ end
34
+
35
+ module ReadTimeoutConvertable
36
+ def rbuf_fill
37
+ begin
38
+ super
39
+ rescue Net::ReadTimeout => error
40
+ raise ReadTimeout, error.message, error.backtrace
41
+ end
42
+ end
43
+ end
44
+
45
+ private
46
+ def on_connect
47
+ @socket.extend(ReadTimeoutConvertable)
48
+ end
49
+ end
50
+
30
51
  include PathResolvable
31
52
 
32
53
  def initialize(url, options={})
@@ -36,7 +57,7 @@ module Groonga
36
57
 
37
58
  def send(command)
38
59
  begin
39
- Net::HTTP.start(@url.host, @url.port, start_options) do |http|
60
+ HTTPClient.start(@url.host, @url.port, start_options) do |http|
40
61
  http.read_timeout = read_timeout
41
62
  response = send_request(http, command)
42
63
  case response
@@ -64,6 +64,14 @@ module Groonga
64
64
  :domain,
65
65
  :range,
66
66
  :source)
67
+ # @return [String]
68
+ # The column name with table name such as `TABLE.COLUMN`.
69
+ #
70
+ # @since 0.5.4
71
+ def full_name
72
+ "#{domain}.#{name}"
73
+ end
74
+
67
75
  # @return [::Array<String>]
68
76
  # The flag names of the column.
69
77
  #
@@ -95,6 +103,8 @@ module Groonga
95
103
  def index?
96
104
  flags.include?("COLUMN_INDEX")
97
105
  end
106
+
107
+ alias_method :sources, :source
98
108
  end
99
109
  end
100
110
  end
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Groonga
18
18
  class Client
19
- VERSION = "0.5.4"
19
+ VERSION = "0.5.5"
20
20
  end
21
21
  end
@@ -0,0 +1,87 @@
1
+ # Copyright (C) 2017 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License as published by the Free Software Foundation; either
6
+ # version 2.1 of the License, or (at your option) any later version.
7
+ #
8
+ # This library is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this library; if not, write to the Free Software
15
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
+
17
+ require "groonga/command/parser"
18
+
19
+ require "groonga/client"
20
+ require "groonga/client/test-helper"
21
+
22
+ module CommandLineTestHelper
23
+ def groonga_url
24
+ @groonga_server_runner.url.to_s
25
+ end
26
+
27
+ def open_client
28
+ Groonga::Client.open(:url => groonga_url) do |client|
29
+ yield(client)
30
+ end
31
+ end
32
+
33
+ def restore(commands)
34
+ open_client do |client|
35
+ values = nil
36
+ Groonga::Command::Parser.parse(commands) do |event, *args|
37
+ case event
38
+ when :on_command
39
+ command, = args
40
+ response = client.execute(command)
41
+ unless response.success?
42
+ raise Groonga::Client::Request::ErrorResponse.new(response)
43
+ end
44
+ when :on_load_start
45
+ command, = args
46
+ values = []
47
+ when :on_load_columns
48
+ command, columns = args
49
+ command[:columns] ||= columns.join(",")
50
+ when :on_load_value
51
+ command, value = args
52
+ values << value
53
+ when :on_load_complete
54
+ command, = args
55
+ command[:values] ||= JSON.generate(values)
56
+ response = client.execute(command)
57
+ unless response.success?
58
+ raise Groonga::Client::Request::ErrorResponse.new(response)
59
+ end
60
+ else
61
+ p [:unhandled_event, event, *args]
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ def dump
68
+ open_client do |client|
69
+ client.dump.body
70
+ end
71
+ end
72
+
73
+ def capture_outputs
74
+ begin
75
+ stdout, $stdout = $stdout, StringIO.new
76
+ stderr, $stderr = $stderr, StringIO.new
77
+ result = yield
78
+ [
79
+ result,
80
+ $stdout.string,
81
+ $stderr.string,
82
+ ]
83
+ ensure
84
+ $stdout, $stderr = stdout, stderr
85
+ end
86
+ end
87
+ end