groonga-client 0.3.3 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/doc/text/news.md +13 -0
- data/lib/groonga/client.rb +1 -1
- data/lib/groonga/client/request.rb +22 -0
- data/lib/groonga/client/request/base.rb +174 -0
- data/lib/groonga/client/request/error.rb +39 -0
- data/lib/groonga/client/request/select.rb +292 -0
- data/lib/groonga/client/response/schema.rb +25 -9
- data/lib/groonga/client/response/select.rb +64 -2
- data/lib/groonga/client/spec-helper.rb +37 -0
- data/lib/groonga/client/test-helper.rb +37 -0
- data/lib/groonga/client/test/fixture.rb +35 -0
- data/lib/groonga/client/test/groonga-server-runner.rb +158 -0
- data/lib/groonga/client/version.rb +1 -1
- data/test/request/select/test-filter-parameter.rb +97 -0
- data/test/request/select/test-output-columns-parameter.rb +75 -0
- data/test/request/select/test-sort-keys-columns-parameter.rb +74 -0
- data/test/request/select/test-values-parameter.rb +58 -0
- data/test/request/test-base.rb +50 -0
- data/test/request/test-select.rb +131 -0
- data/test/response/test-schema.rb +342 -0
- data/test/response/test-select-command-version1.rb +68 -0
- data/test/response/test-select-command-version3.rb +70 -0
- data/test/run-test.rb +1 -0
- metadata +36 -16
@@ -157,6 +157,112 @@ class TestResponseSchema < Test::Unit::TestCase
|
|
157
157
|
assert_equal("Names.users",
|
158
158
|
response.tables["Users"].indexes[0].full_name)
|
159
159
|
end
|
160
|
+
|
161
|
+
sub_test_case "#have_full_text_search_index" do
|
162
|
+
test "no tokenizer" do
|
163
|
+
body = {
|
164
|
+
"tables" => {
|
165
|
+
"Names" => {
|
166
|
+
"name" => "Names",
|
167
|
+
"columns" => {
|
168
|
+
"users_key" => {
|
169
|
+
"name" => "users_key",
|
170
|
+
"position" => true,
|
171
|
+
},
|
172
|
+
},
|
173
|
+
"tokenizer" => nil,
|
174
|
+
},
|
175
|
+
"Users" => {
|
176
|
+
"indexes" => [
|
177
|
+
{
|
178
|
+
"table" => "Names",
|
179
|
+
"name" => "users_key",
|
180
|
+
},
|
181
|
+
],
|
182
|
+
},
|
183
|
+
},
|
184
|
+
}
|
185
|
+
response = create_response(body)
|
186
|
+
table = response.tables["Users"]
|
187
|
+
assert do
|
188
|
+
not table.have_full_text_search_index?
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
test "no position" do
|
193
|
+
body = {
|
194
|
+
"tokenizers" => {
|
195
|
+
"TokenDelimit" => {
|
196
|
+
"name" => "TokenDelimit",
|
197
|
+
},
|
198
|
+
},
|
199
|
+
"tables" => {
|
200
|
+
"Names" => {
|
201
|
+
"name" => "Names",
|
202
|
+
"columns" => {
|
203
|
+
"users_key" => {
|
204
|
+
"name" => "users_key",
|
205
|
+
"position" => false,
|
206
|
+
},
|
207
|
+
},
|
208
|
+
"tokenizer" => {
|
209
|
+
"name" => "TokenDelimit",
|
210
|
+
},
|
211
|
+
},
|
212
|
+
"Users" => {
|
213
|
+
"indexes" => [
|
214
|
+
{
|
215
|
+
"table" => "Names",
|
216
|
+
"name" => "users_key",
|
217
|
+
},
|
218
|
+
],
|
219
|
+
},
|
220
|
+
},
|
221
|
+
}
|
222
|
+
response = create_response(body)
|
223
|
+
table = response.tables["Users"]
|
224
|
+
assert do
|
225
|
+
not table.have_full_text_search_index?
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
test "have tokenizer and position" do
|
230
|
+
body = {
|
231
|
+
"tokenizers" => {
|
232
|
+
"TokenBigram" => {
|
233
|
+
"name" => "TokenBigram",
|
234
|
+
},
|
235
|
+
},
|
236
|
+
"tables" => {
|
237
|
+
"Names" => {
|
238
|
+
"name" => "Names",
|
239
|
+
"columns" => {
|
240
|
+
"users_key" => {
|
241
|
+
"name" => "users_key",
|
242
|
+
"position" => true,
|
243
|
+
},
|
244
|
+
},
|
245
|
+
"tokenizer" => {
|
246
|
+
"name" => "TokenBigram",
|
247
|
+
},
|
248
|
+
},
|
249
|
+
"Users" => {
|
250
|
+
"indexes" => [
|
251
|
+
{
|
252
|
+
"table" => "Names",
|
253
|
+
"name" => "users_key",
|
254
|
+
},
|
255
|
+
],
|
256
|
+
},
|
257
|
+
},
|
258
|
+
}
|
259
|
+
response = create_response(body)
|
260
|
+
table = response.tables["Users"]
|
261
|
+
assert do
|
262
|
+
table.have_full_text_search_index?
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
160
266
|
end
|
161
267
|
|
162
268
|
class TestColumn < self
|
@@ -180,6 +286,130 @@ class TestResponseSchema < Test::Unit::TestCase
|
|
180
286
|
assert_equal("Ages.users",
|
181
287
|
response.tables["Users"].columns["age"].indexes[0].full_name)
|
182
288
|
end
|
289
|
+
|
290
|
+
sub_test_case "#have_full_text_search_index" do
|
291
|
+
test "no tokenizer" do
|
292
|
+
body = {
|
293
|
+
"tables" => {
|
294
|
+
"Names" => {
|
295
|
+
"name" => "Names",
|
296
|
+
"columns" => {
|
297
|
+
"users_name" => {
|
298
|
+
"name" => "users_names",
|
299
|
+
"position" => true,
|
300
|
+
},
|
301
|
+
},
|
302
|
+
"tokenizer" => nil,
|
303
|
+
},
|
304
|
+
"Users" => {
|
305
|
+
"columns" => {
|
306
|
+
"names" => {
|
307
|
+
"name" => "names",
|
308
|
+
"type" => "vector",
|
309
|
+
"indexes" => [
|
310
|
+
{
|
311
|
+
"table" => "Names",
|
312
|
+
"name" => "users_names",
|
313
|
+
},
|
314
|
+
],
|
315
|
+
},
|
316
|
+
},
|
317
|
+
},
|
318
|
+
},
|
319
|
+
}
|
320
|
+
response = create_response(body)
|
321
|
+
column = response.tables["Users"].columns["names"]
|
322
|
+
assert do
|
323
|
+
not column.have_full_text_search_index?
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
test "no position" do
|
328
|
+
body = {
|
329
|
+
"tokenizers" => {
|
330
|
+
"TokenDelimit" => {
|
331
|
+
"name" => "TokenDelimit",
|
332
|
+
},
|
333
|
+
},
|
334
|
+
"tables" => {
|
335
|
+
"Names" => {
|
336
|
+
"name" => "Names",
|
337
|
+
"columns" => {
|
338
|
+
"users_names" => {
|
339
|
+
"name" => "users_names",
|
340
|
+
"position" => false,
|
341
|
+
},
|
342
|
+
},
|
343
|
+
"tokenizer" => {
|
344
|
+
"name" => "TokenDelimit",
|
345
|
+
},
|
346
|
+
},
|
347
|
+
"Users" => {
|
348
|
+
"columns" => {
|
349
|
+
"names" => {
|
350
|
+
"name" => "names",
|
351
|
+
"type" => "vector",
|
352
|
+
"indexes" => [
|
353
|
+
{
|
354
|
+
"table" => "Names",
|
355
|
+
"name" => "users_names",
|
356
|
+
},
|
357
|
+
],
|
358
|
+
},
|
359
|
+
},
|
360
|
+
},
|
361
|
+
},
|
362
|
+
}
|
363
|
+
response = create_response(body)
|
364
|
+
column = response.tables["Users"].columns["names"]
|
365
|
+
assert do
|
366
|
+
not column.have_full_text_search_index?
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
test "have tokenizer and position" do
|
371
|
+
body = {
|
372
|
+
"tokenizers" => {
|
373
|
+
"TokenBigram" => {
|
374
|
+
"name" => "TokenBigram",
|
375
|
+
},
|
376
|
+
},
|
377
|
+
"tables" => {
|
378
|
+
"Names" => {
|
379
|
+
"name" => "Names",
|
380
|
+
"columns" => {
|
381
|
+
"users_name" => {
|
382
|
+
"name" => "users_name",
|
383
|
+
"position" => true,
|
384
|
+
},
|
385
|
+
},
|
386
|
+
"tokenizer" => {
|
387
|
+
"name" => "TokenBigram",
|
388
|
+
},
|
389
|
+
},
|
390
|
+
"Users" => {
|
391
|
+
"columns" => {
|
392
|
+
"name" => {
|
393
|
+
"name" => "name",
|
394
|
+
"type" => "scalar",
|
395
|
+
"indexes" => [
|
396
|
+
{
|
397
|
+
"table" => "Names",
|
398
|
+
"name" => "users_name",
|
399
|
+
},
|
400
|
+
],
|
401
|
+
},
|
402
|
+
},
|
403
|
+
},
|
404
|
+
},
|
405
|
+
}
|
406
|
+
response = create_response(body)
|
407
|
+
column = response.tables["Users"].columns["name"]
|
408
|
+
assert do
|
409
|
+
column.have_full_text_search_index?
|
410
|
+
end
|
411
|
+
end
|
412
|
+
end
|
183
413
|
end
|
184
414
|
|
185
415
|
class TestIndex < self
|
@@ -228,6 +458,118 @@ class TestResponseSchema < Test::Unit::TestCase
|
|
228
458
|
assert_equal(response.tables["Names"].columns["users_key"],
|
229
459
|
response.tables["Users"].indexes[0].column)
|
230
460
|
end
|
461
|
+
|
462
|
+
sub_test_case("#full_text_searchable?") do
|
463
|
+
test "no tokenizer" do
|
464
|
+
body = {
|
465
|
+
"tables" => {
|
466
|
+
"Names" => {
|
467
|
+
"name" => "Names",
|
468
|
+
"columns" => {
|
469
|
+
"users_names" => {
|
470
|
+
"name" => "users_names",
|
471
|
+
"position" => true,
|
472
|
+
},
|
473
|
+
},
|
474
|
+
"tokenizer" => nil,
|
475
|
+
},
|
476
|
+
"Users" => {
|
477
|
+
"columns" => {
|
478
|
+
"names" => {
|
479
|
+
"name" => "names",
|
480
|
+
"type" => "vector",
|
481
|
+
"indexes" => [
|
482
|
+
{
|
483
|
+
"table" => "Names",
|
484
|
+
"name" => "users_names",
|
485
|
+
},
|
486
|
+
],
|
487
|
+
},
|
488
|
+
},
|
489
|
+
},
|
490
|
+
},
|
491
|
+
}
|
492
|
+
response = create_response(body)
|
493
|
+
index = response.tables["Users"].columns["names"].indexes[0]
|
494
|
+
assert do
|
495
|
+
not index.full_text_searchable?
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
test "no position" do
|
500
|
+
body = {
|
501
|
+
"tokenizers" => {
|
502
|
+
"TokenBigram" => {
|
503
|
+
"name" => "TokenBigram",
|
504
|
+
},
|
505
|
+
},
|
506
|
+
"tables" => {
|
507
|
+
"Names" => {
|
508
|
+
"name" => "Names",
|
509
|
+
"columns" => {
|
510
|
+
"users_key" => {
|
511
|
+
"name" => "users_key",
|
512
|
+
"position" => false,
|
513
|
+
},
|
514
|
+
},
|
515
|
+
"tokenizer" => {
|
516
|
+
"name" => "TokenBigram",
|
517
|
+
},
|
518
|
+
},
|
519
|
+
"Users" => {
|
520
|
+
"indexes" => [
|
521
|
+
{
|
522
|
+
"table" => "Names",
|
523
|
+
"name" => "users_key",
|
524
|
+
},
|
525
|
+
]
|
526
|
+
}
|
527
|
+
},
|
528
|
+
}
|
529
|
+
response = create_response(body)
|
530
|
+
index = response.tables["Users"].indexes[0]
|
531
|
+
assert do
|
532
|
+
not index.full_text_searchable?
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
test "have tokenizer and position" do
|
537
|
+
body = {
|
538
|
+
"tokenizers" => {
|
539
|
+
"TokenBigram" => {
|
540
|
+
"name" => "TokenBigram",
|
541
|
+
},
|
542
|
+
},
|
543
|
+
"tables" => {
|
544
|
+
"Names" => {
|
545
|
+
"name" => "Names",
|
546
|
+
"columns" => {
|
547
|
+
"users_key" => {
|
548
|
+
"name" => "users_key",
|
549
|
+
"position" => true,
|
550
|
+
},
|
551
|
+
},
|
552
|
+
"tokenizer" => {
|
553
|
+
"name" => "TokenBigram",
|
554
|
+
},
|
555
|
+
},
|
556
|
+
"Users" => {
|
557
|
+
"indexes" => [
|
558
|
+
{
|
559
|
+
"table" => "Names",
|
560
|
+
"name" => "users_key",
|
561
|
+
},
|
562
|
+
],
|
563
|
+
},
|
564
|
+
},
|
565
|
+
}
|
566
|
+
response = create_response(body)
|
567
|
+
index = response.tables["Users"].indexes[0]
|
568
|
+
assert do
|
569
|
+
index.full_text_searchable?
|
570
|
+
end
|
571
|
+
end
|
572
|
+
end
|
231
573
|
end
|
232
574
|
end
|
233
575
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# Copyright (C) 2013-2016 Kouhei Sutou <kou@clear-code.com>
|
2
2
|
# Copyright (C) 2013 Kosuke Asami
|
3
|
+
# Copyright (C) 2016 Masafumi Yokoyama <yokoyama@clear-code.com>
|
3
4
|
#
|
4
5
|
# This library is free software; you can redistribute it and/or
|
5
6
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -315,5 +316,72 @@ class TestResponseSelectCommandVersion1 < Test::Unit::TestCase
|
|
315
316
|
values
|
316
317
|
end
|
317
318
|
end
|
319
|
+
|
320
|
+
class TestSlices < self
|
321
|
+
def setup
|
322
|
+
pair_arguments = {
|
323
|
+
"slices[groonga].filter" => 'tag @ "groonga"',
|
324
|
+
}
|
325
|
+
@command = Groonga::Command::Select.new("select", pair_arguments)
|
326
|
+
@body = [
|
327
|
+
[
|
328
|
+
[3],
|
329
|
+
[
|
330
|
+
[
|
331
|
+
"_id",
|
332
|
+
"UInt32"
|
333
|
+
],
|
334
|
+
[
|
335
|
+
"tag",
|
336
|
+
"ShortText"
|
337
|
+
]
|
338
|
+
],
|
339
|
+
[1, "groonga"],
|
340
|
+
[2, "rroonga"],
|
341
|
+
[3, "groonga"],
|
342
|
+
],
|
343
|
+
{
|
344
|
+
"groonga" => [
|
345
|
+
[2],
|
346
|
+
[
|
347
|
+
[
|
348
|
+
"_id",
|
349
|
+
"UInt32"
|
350
|
+
],
|
351
|
+
[
|
352
|
+
"tag",
|
353
|
+
"ShortText"
|
354
|
+
]
|
355
|
+
],
|
356
|
+
[1, "groonga"],
|
357
|
+
[3, "groonga"],
|
358
|
+
]
|
359
|
+
}
|
360
|
+
]
|
361
|
+
end
|
362
|
+
|
363
|
+
def test_slices
|
364
|
+
assert_equal({
|
365
|
+
"groonga" => [
|
366
|
+
{"_id" => 1, "tag" => "groonga"},
|
367
|
+
{"_id" => 3, "tag" => "groonga"},
|
368
|
+
]
|
369
|
+
},
|
370
|
+
collect_values(@body, &:records))
|
371
|
+
end
|
372
|
+
|
373
|
+
private
|
374
|
+
def slices(body)
|
375
|
+
create_response(body).slices
|
376
|
+
end
|
377
|
+
|
378
|
+
def collect_values(body)
|
379
|
+
values = {}
|
380
|
+
slices(body).each do |label, slice|
|
381
|
+
values[label] = yield(slice)
|
382
|
+
end
|
383
|
+
values
|
384
|
+
end
|
385
|
+
end
|
318
386
|
end
|
319
387
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# Copyright (C) 2013-2016 Kouhei Sutou <kou@clear-code.com>
|
2
2
|
# Copyright (C) 2013 Kosuke Asami
|
3
|
+
# Copyright (C) 2016 Masafumi Yokoyama <yokoyama@clear-code.com>
|
3
4
|
#
|
4
5
|
# This library is free software; you can redistribute it and/or
|
5
6
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -278,5 +279,74 @@ class TestResponseSelectCommandVersion3 < Test::Unit::TestCase
|
|
278
279
|
values
|
279
280
|
end
|
280
281
|
end
|
282
|
+
|
283
|
+
class TestSlices < self
|
284
|
+
def setup
|
285
|
+
pair_arguments = {
|
286
|
+
"slices[groonga].filter" => 'tag @ "groonga"',
|
287
|
+
}
|
288
|
+
@command = Groonga::Command::Select.new("select", pair_arguments)
|
289
|
+
@body = {
|
290
|
+
"n_hits" => 3,
|
291
|
+
"columns" => [
|
292
|
+
{
|
293
|
+
"name" => "_id",
|
294
|
+
"type" => "UInt32"
|
295
|
+
},
|
296
|
+
{
|
297
|
+
"name" => "tag",
|
298
|
+
"type" => "ShortText"
|
299
|
+
}
|
300
|
+
],
|
301
|
+
"records" => [
|
302
|
+
[1, "groonga"],
|
303
|
+
[2, "rroonga"],
|
304
|
+
[3, "groonga"],
|
305
|
+
],
|
306
|
+
"slices" => {
|
307
|
+
"groonga" => {
|
308
|
+
"n_hits" => 2,
|
309
|
+
"columns" => [
|
310
|
+
{
|
311
|
+
"name" => "_id",
|
312
|
+
"type" => "UInt32"
|
313
|
+
},
|
314
|
+
{
|
315
|
+
"name" => "tag",
|
316
|
+
"type" => "ShortText"
|
317
|
+
}
|
318
|
+
],
|
319
|
+
"records" => [
|
320
|
+
[1, "groonga"],
|
321
|
+
[3, "groonga"],
|
322
|
+
]
|
323
|
+
}
|
324
|
+
}
|
325
|
+
}
|
326
|
+
end
|
327
|
+
|
328
|
+
def test_slices
|
329
|
+
assert_equal({
|
330
|
+
"groonga" => [
|
331
|
+
{"_id" => 1, "tag" => "groonga"},
|
332
|
+
{"_id" => 3, "tag" => "groonga"},
|
333
|
+
]
|
334
|
+
},
|
335
|
+
collect_values(@body, &:records))
|
336
|
+
end
|
337
|
+
|
338
|
+
private
|
339
|
+
def slices(body)
|
340
|
+
create_response(body).slices
|
341
|
+
end
|
342
|
+
|
343
|
+
def collect_values(body)
|
344
|
+
values = {}
|
345
|
+
slices(body).each do |label, slice|
|
346
|
+
values[label] = yield(slice)
|
347
|
+
end
|
348
|
+
values
|
349
|
+
end
|
350
|
+
end
|
281
351
|
end
|
282
352
|
end
|