groonga-client 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,16 +1,142 @@
1
+ # Copyright (C) 2013 Kosuke Asami
2
+ # Copyright (C) 2017 Kouhei Sutou <kou@clear-code.com>
3
+ #
4
+ # This library is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU Lesser General Public
6
+ # License as published by the Free Software Foundation; either
7
+ # version 2.1 of the License, or (at your option) any later version.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
1
18
  require "response/helper"
2
19
 
3
20
  class TestResponseColumnList < Test::Unit::TestCase
4
- include TestResponseHelper
21
+ class TestParse < self
22
+ include TestResponseHelper
23
+
24
+ def column(attributes)
25
+ c = Groonga::Client::Response::ColumnList::Column.new
26
+ attributes.each do |name, value|
27
+ c[name] = value
28
+ end
29
+ c
30
+ end
31
+
32
+ def test_parse
33
+ header = [0, 1372430096.70991, 0.000522851943969727]
34
+ body = [
35
+ [
36
+ ["id", "UInt32"],
37
+ ["name", "ShortText"],
38
+ ["path", "ShortText"],
39
+ ["type", "ShortText"],
40
+ ["flags", "ShortText"],
41
+ ["domain", "ShortText"],
42
+ ["range", "ShortText"],
43
+ ["source", "ShortText"],
44
+ ],
45
+ [
46
+ 256,
47
+ "content",
48
+ "/tmp/test.db.0000100",
49
+ "var",
50
+ "COLUMN_SCALAR|PERSISTENT",
51
+ "TestTable",
52
+ "ShortText",
53
+ [],
54
+ ],
55
+ ]
56
+ raw_response = [header, body].to_json
57
+
58
+ response = parse_raw_response("column_list", raw_response)
59
+ assert_equal([
60
+ column(:id => 256,
61
+ :name => "content",
62
+ :path => "/tmp/test.db.0000100",
63
+ :type => "var",
64
+ :flags => "COLUMN_SCALAR|PERSISTENT",
65
+ :domain => "TestTable",
66
+ :range => "ShortText",
67
+ :source => []),
68
+ ],
69
+ response.to_a)
70
+ end
71
+ end
72
+
73
+ class TestBody < self
74
+ def setup
75
+ @command = Groonga::Command::Base.new("column_list", "table" => "Memos")
76
+ end
77
+
78
+ def create_response(columns)
79
+ header = [0, 1372430096.70991, 0.000522851943969727]
80
+ body = [
81
+ [
82
+ ["id", "UInt32"],
83
+ ["name", "ShortText"],
84
+ ["path", "ShortText"],
85
+ ["type", "ShortText"],
86
+ ["flags", "ShortText"],
87
+ ["domain", "ShortText"],
88
+ ["range", "ShortText"],
89
+ ["source", "ShortText"],
90
+ ],
91
+ *columns,
92
+ ]
93
+ Groonga::Client::Response::ColumnList.new(@command, header, body)
94
+ end
95
+
96
+ class TestFlags < self
97
+ def create_response(flags)
98
+ columns = [
99
+ [
100
+ 256,
101
+ "content",
102
+ "/tmp/test.db.0000100",
103
+ "var",
104
+ flags,
105
+ "Memos",
106
+ "ShortText",
107
+ [],
108
+ ]
109
+ ]
110
+ super(columns)
111
+ end
112
+
113
+ def test_multiple
114
+ response = create_response("COLUMN_SCALAR|PERSISTENT")
115
+ assert_equal(["COLUMN_SCALAR", "PERSISTENT"],
116
+ response[0].flags)
117
+ end
118
+
119
+ def test_scalar?
120
+ response = create_response("COLUMN_SCALAR|PERSISTENT")
121
+ assert do
122
+ response[0].scalar?
123
+ end
124
+ end
5
125
 
6
- def test_column_list
7
- header = [0,1372430096.70991,0.000522851943969727]
8
- body = [[["id","UInt32"],["name","ShortText"],["path","ShortText"],["type","ShortText"],["flags","ShortText"],["domain","ShortText"],["range","ShortText"],["source","ShortText"]],
9
- [256,"Text","/tmp/test.db.0000100","var","COLUMN_SCALAR|PERSISTENT","TestTable","ShortText",[]]]
10
- raw_response = [header, body].to_json
126
+ def test_vector?
127
+ response = create_response("COLUMN_VECTOR|PERSISTENT")
128
+ assert do
129
+ response[0].vector?
130
+ end
131
+ end
11
132
 
12
- response = parse_raw_response("column_list", raw_response)
13
- assert_equal(Groonga::Client::Response::ColumnList, response.class)
133
+ def test_index?
134
+ response = create_response("COLUMN_INDEX|WITH_POSITION|PERSISTENT")
135
+ assert do
136
+ response[0].index?
137
+ end
138
+ end
139
+ end
14
140
  end
15
141
  end
16
142
 
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2016 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2016-2017 Kouhei Sutou <kou@clear-code.com>
2
2
  #
3
3
  # This library is free software; you can redistribute it and/or
4
4
  # modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@ class TestResponseSchema < Test::Unit::TestCase
20
20
  class TestParseRawResponse < self
21
21
  include TestResponseHelper
22
22
 
23
- def test_select
23
+ def test_parse
24
24
  header = [0, 1372430096.70991, 0.000522851943969727]
25
25
  body = {}
26
26
  raw_response = [header, body].to_json
@@ -40,6 +40,139 @@ class TestResponseSchema < Test::Unit::TestCase
40
40
  Groonga::Client::Response::Schema.new(@command, header, body)
41
41
  end
42
42
 
43
+ class TestReferenceShortCut < self
44
+ def test_plugin
45
+ body = {
46
+ "plugins" => {
47
+ "token_filters/stop_word" => {
48
+ "name" => "token_filters/stop_word",
49
+ },
50
+ },
51
+ "types" => {},
52
+ "tokenizers" => {},
53
+ "normalizers" => {},
54
+ "token_filters" => {},
55
+ "tables" => {},
56
+ }
57
+ response = create_response(body)
58
+ assert_equal({"name" => "token_filters/stop_word"},
59
+ response["token_filters/stop_word"])
60
+ end
61
+
62
+ def test_type
63
+ body = {
64
+ "plugins" => {},
65
+ "types" => {
66
+ "ShortText" => {
67
+ "name" => "ShortText",
68
+ },
69
+ },
70
+ "tokenizers" => {},
71
+ "normalizers" => {},
72
+ "token_filters" => {},
73
+ "tables" => {},
74
+ }
75
+ response = create_response(body)
76
+ assert_equal({"name" => "ShortText"},
77
+ response["ShortText"])
78
+ end
79
+
80
+ def test_tokenizer
81
+ body = {
82
+ "plugins" => {},
83
+ "types" => {},
84
+ "tokenizers" => {
85
+ "TokenBigram" => {
86
+ "name" => "TokenBigram",
87
+ },
88
+ },
89
+ "normalizers" => {},
90
+ "token_filters" => {},
91
+ "tables" => {},
92
+ }
93
+ response = create_response(body)
94
+ assert_equal({"name" => "TokenBigram"},
95
+ response["TokenBigram"])
96
+ end
97
+
98
+ def test_normalizer
99
+ body = {
100
+ "plugins" => {},
101
+ "types" => {},
102
+ "tokenizers" => {},
103
+ "normalizers" => {
104
+ "NormalizerAuto" => {
105
+ "name" => "NormalizerAuto",
106
+ },
107
+ },
108
+ "token_filters" => {},
109
+ "tables" => {},
110
+ }
111
+ response = create_response(body)
112
+ assert_equal({"name" => "NormalizerAuto"},
113
+ response["NormalizerAuto"])
114
+ end
115
+
116
+ def test_token_filters
117
+ body = {
118
+ "plugins" => {},
119
+ "types" => {},
120
+ "tokenizers" => {},
121
+ "normalizers" => {},
122
+ "token_filters" => {
123
+ "TokenFilterStopWord" => {
124
+ "name" => "TokenFilterStopWord",
125
+ },
126
+ },
127
+ "tables" => {},
128
+ }
129
+ response = create_response(body)
130
+ assert_equal({"name" => "TokenFilterStopWord"},
131
+ response["TokenFilterStopWord"])
132
+ end
133
+
134
+ def test_table
135
+ body = {
136
+ "plugins" => {},
137
+ "types" => {},
138
+ "tokenizers" => {},
139
+ "normalizers" => {},
140
+ "token_filters" => {},
141
+ "tables" => {
142
+ "Users" => {
143
+ "name" => "Users",
144
+ },
145
+ },
146
+ }
147
+ response = create_response(body)
148
+ assert_equal({"name" => "Users"},
149
+ response["Users"])
150
+ end
151
+
152
+ def test_column
153
+ body = {
154
+ "plugins" => {},
155
+ "types" => {},
156
+ "tokenizers" => {},
157
+ "normalizers" => {},
158
+ "token_filters" => {},
159
+ "tables" => {
160
+ "Users" => {
161
+ "name" => "Users",
162
+ "columns" => {
163
+ "age" => {
164
+ "name" => "age",
165
+ },
166
+ },
167
+ },
168
+ },
169
+ }
170
+ response = create_response(body)
171
+ assert_equal({"name" => "age"},
172
+ response["Users.age"])
173
+ end
174
+ end
175
+
43
176
  class TestTable < self
44
177
  def test_key_type
45
178
  body = {
@@ -263,6 +396,30 @@ class TestResponseSchema < Test::Unit::TestCase
263
396
  end
264
397
  end
265
398
  end
399
+
400
+ def test_command
401
+ body = {
402
+ "tables" => {
403
+ "Users" => {
404
+ "command" => {
405
+ "name" => "table_create",
406
+ "arguments" => {
407
+ "name" => "Users",
408
+ "flags" => "TABLE_HASH_KEY",
409
+ "key_type" => "ShortText",
410
+ },
411
+ }
412
+ }
413
+ }
414
+ }
415
+ response = create_response(body)
416
+ assert_equal({
417
+ "name" => "Users",
418
+ "flags" => "TABLE_HASH_KEY",
419
+ "key_type" => "ShortText",
420
+ },
421
+ response.tables["Users"].command.arguments)
422
+ end
266
423
  end
267
424
 
268
425
  class TestColumn < self
@@ -410,6 +567,36 @@ class TestResponseSchema < Test::Unit::TestCase
410
567
  end
411
568
  end
412
569
  end
570
+
571
+ def test_command
572
+ body = {
573
+ "tables" => {
574
+ "Users" => {
575
+ "columns" => {
576
+ "name" => {
577
+ "command" => {
578
+ "name" => "column_create",
579
+ "arguments" => {
580
+ "table" => "Users",
581
+ "name" => "name",
582
+ "flags" => "COLUMN_SCALAR",
583
+ "type" => "ShortText",
584
+ },
585
+ }
586
+ }
587
+ }
588
+ }
589
+ }
590
+ }
591
+ response = create_response(body)
592
+ assert_equal({
593
+ "table" => "Users",
594
+ "name" => "name",
595
+ "flags" => "COLUMN_SCALAR",
596
+ "type" => "ShortText",
597
+ },
598
+ response.tables["Users"].columns["name"].command.arguments)
599
+ end
413
600
  end
414
601
 
415
602
  class TestIndex < self
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.5.2
4
+ version: 0.5.3
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: 2017-09-27 00:00:00.000000000 Z
13
+ date: 2017-10-26 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: gqtp
@@ -161,6 +161,7 @@ email:
161
161
  - kou@clear-code.com
162
162
  - tfortress58@gmail.com
163
163
  executables:
164
+ - groonga-client-index-recreate
164
165
  - groonga-client
165
166
  extensions: []
166
167
  extra_rdoc_files: []
@@ -170,11 +171,13 @@ files:
170
171
  - README.md
171
172
  - Rakefile
172
173
  - bin/groonga-client
174
+ - bin/groonga-client-index-recreate
173
175
  - doc/text/lgpl-2.1.txt
174
176
  - doc/text/news.md
175
177
  - groonga-client.gemspec
176
178
  - lib/groonga/client.rb
177
- - lib/groonga/client/cli.rb
179
+ - lib/groonga/client/command-line/groonga-client-index-recreate.rb
180
+ - lib/groonga/client/command-line/groonga-client.rb
178
181
  - lib/groonga/client/command.rb
179
182
  - lib/groonga/client/default.rb
180
183
  - lib/groonga/client/empty-request.rb
@@ -221,6 +224,7 @@ files:
221
224
  - lib/groonga/client/test/fixture.rb
222
225
  - lib/groonga/client/test/groonga-server-runner.rb
223
226
  - lib/groonga/client/version.rb
227
+ - test/command-line/test-index-recreate.rb
224
228
  - test/protocol/test-gqtp.rb
225
229
  - test/protocol/test-http.rb
226
230
  - test/request/select/test-backward-compatible-sort-keys-parameter.rb
@@ -245,7 +249,6 @@ files:
245
249
  - test/response/test-table-create.rb
246
250
  - test/response/test-table-list.rb
247
251
  - test/response/test-table-remove.rb
248
- - test/results/test-column-list.rb
249
252
  - test/results/test-table-list.rb
250
253
  - test/run-test.rb
251
254
  - test/test-client.rb
@@ -271,13 +274,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
271
274
  version: '0'
272
275
  requirements: []
273
276
  rubyforge_project:
274
- rubygems_version: 2.5.2
277
+ rubygems_version: 2.5.2.1
275
278
  signing_key:
276
279
  specification_version: 4
277
280
  summary: Groonga-client is a client for Groonga (http://groonga.org/) implemented
278
281
  with pure Ruby. You can use it without Groonga.
279
282
  test_files:
280
283
  - test/test-client.rb
284
+ - test/command-line/test-index-recreate.rb
281
285
  - test/test-script-syntax.rb
282
286
  - test/request/select/test-backward-compatible-sort-keys-parameter.rb
283
287
  - test/request/select/test-filter.rb
@@ -305,5 +309,4 @@ test_files:
305
309
  - test/response/test-select-command-version1.rb
306
310
  - test/response/test-table-create.rb
307
311
  - test/response/test-table-remove.rb
308
- - test/results/test-column-list.rb
309
312
  - test/results/test-table-list.rb
@@ -1,233 +0,0 @@
1
- # Copyright (C) 2015-2016 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 "ostruct"
18
- require "optparse"
19
- require "json"
20
- require "securerandom"
21
-
22
- require "groonga/client"
23
-
24
- require "groonga/command/parser"
25
-
26
- module Groonga
27
- class Client
28
- class CLI
29
- def initialize
30
- @protocol = :http
31
- @host = "localhost"
32
- @port = nil
33
-
34
- @read_timeout = Client::Default::READ_TIMEOUT
35
-
36
- @chunk = false
37
-
38
- @runner_options = {
39
- :split_load_chunk_size => 10000,
40
- :generate_request_id => false,
41
- }
42
- end
43
-
44
- def run(argv)
45
- command_file_paths = parse_command_line(argv)
46
-
47
- @client = Client.new(:protocol => @protocol,
48
- :host => @host,
49
- :port => @port,
50
- :read_timeout => @read_timeout,
51
- :chunk => @chunk,
52
- :backend => :synchronous)
53
- runner = Runner.new(@client, @runner_options)
54
-
55
- if command_file_paths.empty?
56
- $stdin.each_line do |line|
57
- runner << line
58
- end
59
- else
60
- command_file_paths.each do |command_file_path|
61
- File.open(command_file_path) do |command_file|
62
- last_line = nil
63
- command_file.each_line do |line|
64
- last_line = line
65
- runner << line
66
- end
67
- if last_line and !last_line.end_with?("\n")
68
- runner << "\n"
69
- end
70
- end
71
- end
72
- end
73
- runner.finish
74
-
75
- true
76
- end
77
-
78
- private
79
- def parse_command_line(argv)
80
- parser = OptionParser.new
81
- parser.version = VERSION
82
- parser.banner += " GROONGA_COMMAND_FILE1 GROONGA_COMMAND_FILE2 ..."
83
-
84
- parser.separator("")
85
-
86
- parser.separator("Connection:")
87
-
88
- available_protocols = [:http, :gqtp]
89
- parser.on("--protocol=PROTOCOL", [:http, :gqtp],
90
- "Protocol to connect to Groonga server.",
91
- "[#{available_protocols.join(", ")}]",
92
- "(#{@protocol})") do |protocol|
93
- @protocol = protocol
94
- end
95
-
96
- parser.on("--host=HOST",
97
- "Groonga server to be connected.",
98
- "(#{@host})") do |host|
99
- @host = host
100
- end
101
-
102
- parser.on("--port=PORT", Integer,
103
- "Port number of Groonga server to be connected.",
104
- "(auto)") do |port|
105
- @port = port
106
- end
107
-
108
- parser.on("--read-timeout=TIMEOUT", Integer,
109
- "Timeout on reading response from Groonga server.",
110
- "You can disable timeout by specifying -1.",
111
- "(#{@read_timeout})") do |timeout|
112
- @read_timeout = timeout
113
- end
114
-
115
- parser.on("--split-load-chunk-size=SIZE", Integer,
116
- "Split a large load to small loads.",
117
- "Each small load has at most SIZE records.",
118
- "Set 0 to SIZE to disable this feature.",
119
- "(#{@runner_options[:split_load_chunk_size]})") do |size|
120
- @runner_options[:split_load_chunk_size] = size
121
- end
122
-
123
- parser.on("--[no-]generate-request-id",
124
- "Add auto generated request ID to all commands.",
125
- "(#{@runner_options[:generate_request_id]})") do |boolean|
126
- @runner_options[:generate_request_id] = boolean
127
- end
128
-
129
- parser.on("--[no-]chunk",
130
- "Use \"Transfer-Encoding: chunked\" for load command.",
131
- "HTTP only.",
132
- "(#{@chunk})") do |boolean|
133
- @chunk = boolean
134
- end
135
-
136
- command_file_paths = parser.parse(argv)
137
-
138
- @port ||= default_port(@protocol)
139
-
140
- command_file_paths
141
- end
142
-
143
- def default_port(protocol)
144
- case protocol
145
- when :http
146
- 10041
147
- when :gqtp
148
- 10043
149
- end
150
- end
151
-
152
- class Runner
153
- def initialize(client, options={})
154
- @client = client
155
- @split_load_chunk_size = options[:split_load_chunk_size] || 10000
156
- @generate_request_id = options[:generate_request_id]
157
- @load_values = []
158
- @parser = create_command_parser
159
- end
160
-
161
- def <<(line)
162
- @parser << line
163
- end
164
-
165
- def finish
166
- @parser.finish
167
- end
168
-
169
- private
170
- def create_command_parser
171
- parser = Groonga::Command::Parser.new
172
-
173
- parser.on_command do |command|
174
- run_command(command)
175
- end
176
-
177
- parser.on_load_columns do |command, columns|
178
- command[:columns] ||= columns.join(",")
179
- end
180
-
181
- parser.on_load_value do |command, value|
182
- unless command[:values]
183
- @load_values << value
184
- if @load_values.size == @split_load_chunk_size
185
- consume_load_values(command)
186
- end
187
- end
188
- command.original_source.clear
189
- end
190
-
191
- parser.on_load_complete do |command|
192
- if command[:values]
193
- run_command(command)
194
- else
195
- consume_load_values(command)
196
- end
197
- end
198
-
199
- parser
200
- end
201
-
202
- def consume_load_values(load_command)
203
- return if @load_values.empty?
204
-
205
- values_json = "["
206
- @load_values.each_with_index do |value, i|
207
- values_json << "," unless i.zero?
208
- values_json << "\n"
209
- values_json << JSON.generate(value)
210
- end
211
- values_json << "\n]\n"
212
- load_command[:values] = values_json
213
- run_command(load_command)
214
- @load_values.clear
215
- load_command[:values] = nil
216
- end
217
-
218
- def run_command(command)
219
- command[:request_id] ||= SecureRandom.uuid if @generate_request_id
220
- response = @client.execute(command)
221
- case command.output_type
222
- when :json
223
- puts(JSON.pretty_generate([response.header, response.body]))
224
- when :xml
225
- puts(response.raw)
226
- else
227
- puts(response.body)
228
- end
229
- end
230
- end
231
- end
232
- end
233
- end