groonga-client 0.6.5 → 0.6.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c6eb335d9ea4011c1e5b3681dfd8e9252796b95d24c802df1a769757821b8bf
4
- data.tar.gz: 19824fe10455c126d229c1af171a8483ee67b15df08df78a9b8ec43dc0e661cd
3
+ metadata.gz: ad8ac6fe851f63509ad13e5c8abb1541ff2f47631764b86bc23ffc85719ae56a
4
+ data.tar.gz: 558bc6f1e08568791ca791a3be107b9f075864096bf003ca9cb37dc273a7479b
5
5
  SHA512:
6
- metadata.gz: b48b94c52345192fbb20ffbde0d450cd819ca97097b4b0a549ed285645f7a85278392ce51abefb29b055c8505aca5574789e0312fc81b6a7615eeed261e57933
7
- data.tar.gz: 2d58742abe16488dbcfcde075d9102b3988f27b58e8c398a60ba75406d0b17e11ac2ebf8d708c7ebe1b9e7b1a13adad0a59fdabaf646cd376c3463925f7f9f5c
6
+ metadata.gz: 9bde0f05e3d9a17f545bacad7cd6c91099ea65e1371d015860b5f18d714b31d875ba615b21ac6c8bba15333ce7f760b673c6ecf31e8daa8ebc726b79f53618a8
7
+ data.tar.gz: e992b6e14dac0073485a909886c128acca19af991a9d45dc89a57ed1557754a9ab5fe38edd687bcbd86a571dc0155264752b671cf1861e2353c9a12f40309507
data/doc/text/news.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # NEWS
2
2
 
3
+ ## 0.6.6 - 2021-12-10
4
+
5
+ ### Improvements
6
+
7
+ * `Groonga::Client::CommandProcessor`: Extracted Groonga command processor
8
+ from `groonga-client` command implementation.
9
+
3
10
  ## 0.6.5 - 2021-03-15
4
11
 
5
12
  ### Fixes
@@ -73,22 +73,11 @@ module Groonga
73
73
  end
74
74
  repl.run
75
75
  else
76
- $stdin.each_line do |line|
77
- runner << line
78
- end
76
+ runner.consume($stdin)
79
77
  end
80
78
  else
81
79
  command_file_paths.each do |command_file_path|
82
- File.open(command_file_path) do |command_file|
83
- last_line = nil
84
- command_file.each_line do |line|
85
- last_line = line
86
- runner << line
87
- end
88
- if last_line and !last_line.end_with?("\n")
89
- runner << "\n"
90
- end
91
- end
80
+ runner.load(command_file_path)
92
81
  end
93
82
  end
94
83
  runner.finish
@@ -173,95 +162,9 @@ module Groonga
173
162
  end
174
163
  end
175
164
 
176
- class Runner
177
- def initialize(client, options={})
178
- @client = client
179
- @split_load_chunk_size = options[:split_load_chunk_size] || 10000
180
- @generate_request_id = options[:generate_request_id]
181
- @target_commands = options[:target_commands]
182
- @target_tables = options[:target_tables]
183
- @target_columns = options[:target_columns]
184
- @load_values = []
185
- @parser = create_command_parser
186
- end
187
-
188
- def <<(line)
189
- @parser << line
190
- end
191
-
192
- def finish
193
- @parser.finish
194
- end
195
-
196
- def repl
197
- begin
198
- require "readline"
199
- rescue LoadError
200
- repl = BareREPL.new(self)
201
- else
202
- repl = ReadlineREPL.new(self)
203
- repl_readline
204
- end
205
- end
206
-
165
+ class Runner < CommandProcessor
207
166
  private
208
- def create_command_parser
209
- parser = Groonga::Command::Parser.new
210
-
211
- parser.on_command do |command|
212
- run_command(command)
213
- end
214
-
215
- parser.on_load_columns do |command, columns|
216
- command[:columns] ||= columns.join(",")
217
- end
218
-
219
- parser.on_load_value do |command, value|
220
- unless command[:values]
221
- @load_values << value
222
- if @load_values.size == @split_load_chunk_size
223
- consume_load_values(command)
224
- end
225
- end
226
- command.original_source.clear
227
- end
228
-
229
- parser.on_load_complete do |command|
230
- if command[:values]
231
- run_command(command)
232
- else
233
- consume_load_values(command)
234
- end
235
- end
236
-
237
- parser
238
- end
239
-
240
- def consume_load_values(load_command)
241
- return if @load_values.empty?
242
-
243
- values_json = "["
244
- @load_values.each_with_index do |value, i|
245
- values_json << "," unless i.zero?
246
- values_json << "\n"
247
- values_json << JSON.generate(value)
248
- end
249
- values_json << "\n]\n"
250
- load_command[:values] = values_json
251
- run_command(load_command)
252
- @load_values.clear
253
- load_command[:values] = nil
254
- end
255
-
256
- def run_command(command)
257
- return unless target_command?(command)
258
- return unless target_table?(command)
259
- return unless target_column?(command)
260
-
261
- command = Marshal.load(Marshal.dump(command))
262
- apply_target_columns(command)
263
- command[:request_id] ||= SecureRandom.uuid if @generate_request_id
264
- response = @client.execute(command)
167
+ def process_response(response, command)
265
168
  case command.output_type
266
169
  when :json
267
170
  puts(JSON.pretty_generate([response.header, response.body]))
@@ -271,92 +174,6 @@ module Groonga
271
174
  puts(response.body)
272
175
  end
273
176
  end
274
-
275
- def target_command?(command)
276
- return true if @target_commands.empty?
277
-
278
- @target_commands.any? do |name|
279
- name === command.command_name
280
- end
281
- end
282
-
283
- def target_table?(command)
284
- return true if @target_tables.empty?
285
-
286
- target = nil
287
- case command.command_name
288
- when "load", "column_create", "select"
289
- target = command.table
290
- when "table_create", "table_remove"
291
- target = command.name
292
- end
293
- return true if target.nil?
294
-
295
- @target_tables.any? do |name|
296
- name === target
297
- end
298
- end
299
-
300
- def target_column?(command)
301
- return true if @target_columns.empty?
302
-
303
- target = nil
304
- case command.command_name
305
- when "column_create"
306
- target = command.name
307
- end
308
- return true if target.nil?
309
-
310
- @target_columns.any? do |name|
311
- name === target
312
- end
313
- end
314
-
315
- def apply_target_columns(command)
316
- return if @target_columns.empty?
317
-
318
- values = command[:values]
319
- return if values.nil?
320
-
321
- command = command.dup
322
-
323
- values = JSON.parse(values)
324
- columns = command[:columns]
325
- if columns
326
- columns = columns.split(/\s*,\s*/)
327
- target_indexes = []
328
- new_columns = []
329
- columns.each_with_index do |column, i|
330
- if load_target_column?(column)
331
- target_indexes << i
332
- new_columns << column
333
- end
334
- end
335
- command[:columns] = new_columns.join(",")
336
- new_values = values.collect do |value|
337
- target_indexes.collect do |i|
338
- value[i]
339
- end
340
- end
341
- command[:values] = JSON.generate(new_values)
342
- else
343
- new_values = values.collect do |value|
344
- new_value = {}
345
- value.each do |key, value|
346
- if load_target_column?(key)
347
- new_value[key] = value
348
- end
349
- end
350
- new_value
351
- end
352
- command[:values] = JSON.generate(new_values)
353
- end
354
- end
355
-
356
- def load_target_column?(column)
357
- column == "_key" or
358
- @target_columns.any? {|name| name === column}
359
- end
360
177
  end
361
178
 
362
179
  class BareREPL
@@ -0,0 +1,211 @@
1
+ # Copyright (C) 2015-2021 Sutou Kouhei <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 "json"
18
+
19
+ require "groonga/command/parser"
20
+
21
+ module Groonga
22
+ class Client
23
+ class CommandProcessor
24
+ def initialize(client, options={})
25
+ @client = client
26
+ @split_load_chunk_size = options[:split_load_chunk_size] || 10000
27
+ @generate_request_id = options[:generate_request_id]
28
+ @target_commands = options[:target_commands]
29
+ @target_tables = options[:target_tables]
30
+ @target_columns = options[:target_columns]
31
+ @load_values = []
32
+ @parser = create_command_parser
33
+ end
34
+
35
+ def <<(line)
36
+ @parser << line
37
+ end
38
+
39
+ def finish
40
+ @parser.finish
41
+ end
42
+
43
+ def consume(input)
44
+ last_line = nil
45
+ input.each_line do |line|
46
+ last_line = line
47
+ @parser << line
48
+ end
49
+ if last_line and last_line.end_with?("\n")
50
+ @parser << "\n"
51
+ end
52
+ end
53
+
54
+ def load(path)
55
+ File.open(path) do |input|
56
+ consume(input)
57
+ end
58
+ end
59
+
60
+ private
61
+ def create_command_parser
62
+ parser = Groonga::Command::Parser.new
63
+
64
+ parser.on_command do |command|
65
+ run_command(command)
66
+ end
67
+
68
+ parser.on_load_columns do |command, columns|
69
+ command[:columns] ||= columns.join(",")
70
+ end
71
+
72
+ parser.on_load_value do |command, value|
73
+ unless command[:values]
74
+ @load_values << value
75
+ if @load_values.size == @split_load_chunk_size
76
+ consume_load_values(command)
77
+ end
78
+ end
79
+ command.original_source.clear
80
+ end
81
+
82
+ parser.on_load_complete do |command|
83
+ if command[:values]
84
+ run_command(command)
85
+ else
86
+ consume_load_values(command)
87
+ end
88
+ end
89
+
90
+ parser
91
+ end
92
+
93
+ def consume_load_values(load_command)
94
+ return if @load_values.empty?
95
+
96
+ values_json = "["
97
+ @load_values.each_with_index do |value, i|
98
+ values_json << "," unless i.zero?
99
+ values_json << "\n"
100
+ values_json << JSON.generate(value)
101
+ end
102
+ values_json << "\n]\n"
103
+ load_command[:values] = values_json
104
+ run_command(load_command)
105
+ @load_values.clear
106
+ load_command[:values] = nil
107
+ end
108
+
109
+ def run_command(command)
110
+ return unless target_command?(command)
111
+ return unless target_table?(command)
112
+ return unless target_column?(command)
113
+
114
+ command = Marshal.load(Marshal.dump(command))
115
+ apply_target_columns(command)
116
+ command[:request_id] ||= SecureRandom.uuid if @generate_request_id
117
+ response = @client.execute(command)
118
+ process_response(response, command)
119
+ end
120
+
121
+ def process_response(response, command)
122
+ end
123
+
124
+ def target_command?(command)
125
+ return true if @target_commands.empty?
126
+
127
+ @target_commands.any? do |name|
128
+ name === command.command_name
129
+ end
130
+ end
131
+
132
+ def target_table?(command)
133
+ return true if @target_tables.empty?
134
+
135
+ target = nil
136
+ case command.command_name
137
+ when "load", "column_create", "select"
138
+ target = command.table
139
+ when "table_create", "table_remove"
140
+ target = command.name
141
+ end
142
+ return true if target.nil?
143
+
144
+ @target_tables.any? do |name|
145
+ name === target
146
+ end
147
+ end
148
+
149
+ def target_column?(command)
150
+ return true if @target_columns.empty?
151
+
152
+ target = nil
153
+ case command.command_name
154
+ when "column_create"
155
+ target = command.name
156
+ end
157
+ return true if target.nil?
158
+
159
+ @target_columns.any? do |name|
160
+ name === target
161
+ end
162
+ end
163
+
164
+ def apply_target_columns(command)
165
+ return if @target_columns.empty?
166
+
167
+ values = command[:values]
168
+ return if values.nil?
169
+
170
+ command = command.dup
171
+
172
+ values = JSON.parse(values)
173
+ columns = command[:columns]
174
+ if columns
175
+ columns = columns.split(/\s*,\s*/)
176
+ target_indexes = []
177
+ new_columns = []
178
+ columns.each_with_index do |column, i|
179
+ if load_target_column?(column)
180
+ target_indexes << i
181
+ new_columns << column
182
+ end
183
+ end
184
+ command[:columns] = new_columns.join(",")
185
+ new_values = values.collect do |value|
186
+ target_indexes.collect do |i|
187
+ value[i]
188
+ end
189
+ end
190
+ command[:values] = JSON.generate(new_values)
191
+ else
192
+ new_values = values.collect do |value|
193
+ new_value = {}
194
+ value.each do |key, value|
195
+ if load_target_column?(key)
196
+ new_value[key] = value
197
+ end
198
+ end
199
+ new_value
200
+ end
201
+ command[:values] = JSON.generate(new_values)
202
+ end
203
+ end
204
+
205
+ def load_target_column?(column)
206
+ column == "_key" or
207
+ @target_columns.any? {|name| name === column}
208
+ end
209
+ end
210
+ end
211
+ end
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Groonga
18
18
  class Client
19
- VERSION = "0.6.5"
19
+ VERSION = "0.6.6"
20
20
  end
21
21
  end
@@ -18,12 +18,13 @@
18
18
  require "uri"
19
19
  require "json"
20
20
 
21
- require "groonga/client/default"
22
21
  require "groonga/client/command"
22
+ require "groonga/client/command-processor"
23
+ require "groonga/client/default"
23
24
  require "groonga/client/empty-request"
25
+ require "groonga/client/protocol/file"
24
26
  require "groonga/client/protocol/gqtp"
25
27
  require "groonga/client/protocol/http"
26
- require "groonga/client/protocol/file"
27
28
  require "groonga/client/request"
28
29
 
29
30
  module Groonga
@@ -202,7 +203,7 @@ module Groonga
202
203
  end
203
204
 
204
205
  def method_missing(name, *args, &block)
205
- if groonga_command_name?(name)
206
+ if groonga_command_name?(name) and args.size <= 1
206
207
  execute(name, *args, &block)
207
208
  else
208
209
  super
data/test/test-command.rb CHANGED
@@ -5,7 +5,8 @@ class TestCommand < Test::Unit::TestCase
5
5
 
6
6
  def test_column_create
7
7
  response = Object.new
8
- mock(@client).execute(:column_create, :table => :Test, :name => :Body, :type => :ShortText) do
8
+ mock(@client).execute(:column_create,
9
+ {table: :Test, name: :Body, type: :ShortText}) do
9
10
  response
10
11
  end
11
12
  @client.column_create(:table => :Test, :name => :Body, :type => :ShortText)
@@ -13,7 +14,7 @@ class TestCommand < Test::Unit::TestCase
13
14
 
14
15
  def test_column_list
15
16
  response = Object.new
16
- mock(@client).execute(:column_list, :table => :Test) do
17
+ mock(@client).execute(:column_list, {table: :Test}) do
17
18
  response
18
19
  end
19
20
  @client.column_list(:table => :Test)
@@ -27,7 +28,7 @@ class TestCommand < Test::Unit::TestCase
27
28
  }
28
29
  ]
29
30
  response = Object.new
30
- mock(@client).execute(:load, :table => :Test, :values => values.to_json) do
31
+ mock(@client).execute(:load, {table: :Test, values: values.to_json}) do
31
32
  response
32
33
  end
33
34
  @client.load(:table => :Test, :values => values.to_json)
@@ -35,7 +36,7 @@ class TestCommand < Test::Unit::TestCase
35
36
 
36
37
  def test_select
37
38
  response = Object.new
38
- mock(@client).execute(:select, :table => :Test) do
39
+ mock(@client).execute(:select, {table: :Test}) do
39
40
  response
40
41
  end
41
42
  @client.select(:table => :Test)
@@ -43,7 +44,7 @@ class TestCommand < Test::Unit::TestCase
43
44
 
44
45
  def test_table_create
45
46
  response = Object.new
46
- mock(@client).execute(:table_create, :name => :Test) do
47
+ mock(@client).execute(:table_create, {name: :Test}) do
47
48
  response
48
49
  end
49
50
  @client.table_create(:name => :Test)
@@ -58,7 +59,7 @@ class TestCommand < Test::Unit::TestCase
58
59
  end
59
60
 
60
61
  def test_table_remove
61
- mock(@client).execute(:table_remove, :name => "Test")
62
+ mock(@client).execute(:table_remove, {name: "Test"})
62
63
  @client.table_remove(:name => "Test")
63
64
  end
64
65
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: groonga-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.5
4
+ version: 0.6.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Haruka Yoshihara
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2021-03-15 00:00:00.000000000 Z
13
+ date: 2021-12-10 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: gqtp
@@ -197,6 +197,7 @@ files:
197
197
  - lib/groonga/client/command-line/groonga-client.rb
198
198
  - lib/groonga/client/command-line/parser.rb
199
199
  - lib/groonga/client/command-line/runner.rb
200
+ - lib/groonga/client/command-processor.rb
200
201
  - lib/groonga/client/command.rb
201
202
  - lib/groonga/client/default.rb
202
203
  - lib/groonga/client/empty-request.rb