fluent-plugin-droonga 0.9.0 → 0.9.9

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.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -0
  3. data/Gemfile +8 -1
  4. data/fluent-plugin-droonga.gemspec +2 -2
  5. data/lib/droonga/adapter.rb +39 -0
  6. data/lib/droonga/adapter_runner.rb +99 -0
  7. data/lib/droonga/catalog/base.rb +11 -11
  8. data/lib/droonga/catalog/dataset.rb +54 -0
  9. data/lib/droonga/catalog/version1.rb +1 -1
  10. data/lib/droonga/collector.rb +5 -7
  11. data/lib/droonga/collector_plugin.rb +7 -7
  12. data/lib/droonga/command.rb +36 -0
  13. data/lib/droonga/{plugin/input_adapter/crud.rb → command_repository.rb} +14 -8
  14. data/lib/droonga/dispatcher.rb +86 -54
  15. data/lib/droonga/distributed_command_planner.rb +183 -0
  16. data/lib/droonga/distributor.rb +43 -17
  17. data/lib/droonga/handler.rb +13 -72
  18. data/lib/droonga/handler_message.rb +5 -5
  19. data/lib/droonga/handler_messenger.rb +4 -1
  20. data/lib/droonga/handler_plugin.rb +2 -2
  21. data/lib/droonga/handler_runner.rb +104 -0
  22. data/lib/droonga/input_message.rb +4 -4
  23. data/lib/droonga/legacy_pluggable.rb +66 -0
  24. data/lib/droonga/{input_adapter.rb → legacy_plugin.rb} +27 -22
  25. data/lib/droonga/{plugin_repository.rb → legacy_plugin_repository.rb} +2 -4
  26. data/lib/droonga/message_matcher.rb +101 -0
  27. data/lib/droonga/{input_adapter_plugin.rb → planner.rb} +14 -10
  28. data/lib/droonga/planner_plugin.rb +54 -0
  29. data/lib/droonga/pluggable.rb +9 -45
  30. data/lib/droonga/plugin.rb +9 -33
  31. data/lib/droonga/plugin/collector/basic.rb +2 -0
  32. data/lib/droonga/plugin/collector/search.rb +31 -37
  33. data/lib/droonga/plugin/{handler/groonga/table_remove.rb → metadata/adapter_message.rb} +23 -18
  34. data/lib/droonga/plugin/{handler/search.rb → metadata/handler_action.rb} +19 -15
  35. data/lib/droonga/plugin/metadata/input_message.rb +39 -0
  36. data/lib/droonga/plugin/planner/crud.rb +49 -0
  37. data/lib/droonga/plugin/{distributor → planner}/distributed_search_planner.rb +62 -70
  38. data/lib/droonga/plugin/{distributor → planner}/groonga.rb +11 -32
  39. data/lib/droonga/plugin/{distributor → planner}/search.rb +5 -5
  40. data/lib/droonga/plugin/{distributor → planner}/watch.rb +15 -6
  41. data/lib/droonga/plugin_loader.rb +10 -0
  42. data/lib/droonga/plugin_registerable.rb +34 -10
  43. data/lib/droonga/plugin_registry.rb +58 -0
  44. data/lib/droonga/plugins/crud.rb +124 -0
  45. data/lib/droonga/plugins/error.rb +50 -0
  46. data/lib/droonga/{output_adapter_plugin.rb → plugins/groonga.rb} +9 -13
  47. data/lib/droonga/plugins/groonga/column_create.rb +123 -0
  48. data/lib/droonga/plugins/groonga/generic_command.rb +65 -0
  49. data/lib/droonga/{plugin/output_adapter/groonga.rb → plugins/groonga/generic_response.rb} +16 -15
  50. data/lib/droonga/plugins/groonga/select.rb +124 -0
  51. data/lib/droonga/plugins/groonga/table_create.rb +106 -0
  52. data/lib/droonga/plugins/groonga/table_remove.rb +57 -0
  53. data/lib/droonga/plugins/search.rb +40 -0
  54. data/lib/droonga/plugins/watch.rb +156 -0
  55. data/lib/droonga/processor.rb +8 -10
  56. data/lib/droonga/searcher.rb +14 -4
  57. data/lib/droonga/searcher/mecab_filter.rb +67 -0
  58. data/lib/droonga/session.rb +5 -5
  59. data/lib/droonga/test.rb +1 -1
  60. data/lib/droonga/test/stub_handler_message.rb +1 -1
  61. data/lib/droonga/test/{stub_distributor.rb → stub_planner.rb} +1 -1
  62. data/lib/droonga/worker.rb +7 -8
  63. data/lib/fluent/plugin/out_droonga.rb +0 -1
  64. data/sample/cluster/catalog.json +2 -4
  65. data/sample/mecab_filter/data.grn +7 -0
  66. data/sample/mecab_filter/ddl.grn +7 -0
  67. data/sample/mecab_filter/search_with_mecab_filter.json +21 -0
  68. data/sample/mecab_filter/search_without_mecab_filter.json +21 -0
  69. data/test/command/config/default/catalog.json +2 -5
  70. data/test/command/suite/search/error/no-query.expected +13 -0
  71. data/test/command/suite/search/error/no-query.test +7 -0
  72. data/test/command/suite/search/error/unknown-source.expected +26 -0
  73. data/test/command/suite/watch/subscribe.expected +3 -3
  74. data/test/command/suite/watch/unsubscribe.expected +3 -3
  75. data/test/unit/catalog/test_dataset.rb +385 -0
  76. data/test/unit/catalog/test_version1.rb +111 -45
  77. data/test/unit/fixtures/catalog/version1.json +0 -3
  78. data/test/unit/helper.rb +2 -1
  79. data/test/unit/helper/distributed_search_planner_helper.rb +83 -0
  80. data/test/unit/plugin/collector/test_basic.rb +233 -376
  81. data/test/unit/plugin/collector/test_search.rb +8 -17
  82. data/test/unit/plugin/planner/search_planner/test_basic.rb +120 -0
  83. data/test/unit/plugin/planner/search_planner/test_group_by.rb +573 -0
  84. data/test/unit/plugin/planner/search_planner/test_output.rb +388 -0
  85. data/test/unit/plugin/planner/search_planner/test_sort_by.rb +938 -0
  86. data/test/unit/plugin/{distributor → planner}/test_search.rb +20 -75
  87. data/test/unit/{plugin/handler → plugins/crud}/test_add.rb +11 -11
  88. data/test/unit/plugins/groonga/select/test_adapter_input.rb +213 -0
  89. data/test/unit/{plugin/output_adapter/groonga/test_select.rb → plugins/groonga/select/test_adapter_output.rb} +12 -13
  90. data/test/unit/{plugin/handler → plugins}/groonga/test_column_create.rb +20 -5
  91. data/test/unit/{plugin/handler → plugins}/groonga/test_table_create.rb +5 -0
  92. data/test/unit/{plugin/handler → plugins}/groonga/test_table_remove.rb +8 -1
  93. data/test/unit/{plugin/handler → plugins}/test_groonga.rb +5 -5
  94. data/test/unit/{plugin/handler → plugins}/test_search.rb +21 -5
  95. data/test/unit/{plugin/handler → plugins}/test_watch.rb +29 -10
  96. data/{lib/droonga/command_mapper.rb → test/unit/test_command_repository.rb} +16 -22
  97. data/test/unit/{test_plugin.rb → test_legacy_plugin.rb} +3 -3
  98. data/test/unit/{test_plugin_repository.rb → test_legacy_plugin_repository.rb} +3 -3
  99. data/test/unit/test_message_matcher.rb +137 -0
  100. metadata +86 -66
  101. data/bin/grn2jsons +0 -82
  102. data/lib/droonga/distribution_planner.rb +0 -76
  103. data/lib/droonga/distributor_plugin.rb +0 -95
  104. data/lib/droonga/output_adapter.rb +0 -53
  105. data/lib/droonga/plugin/collector/groonga.rb +0 -83
  106. data/lib/droonga/plugin/distributor/crud.rb +0 -84
  107. data/lib/droonga/plugin/handler/add.rb +0 -109
  108. data/lib/droonga/plugin/handler/forward.rb +0 -75
  109. data/lib/droonga/plugin/handler/groonga.rb +0 -99
  110. data/lib/droonga/plugin/handler/groonga/column_create.rb +0 -106
  111. data/lib/droonga/plugin/handler/groonga/table_create.rb +0 -91
  112. data/lib/droonga/plugin/handler/watch.rb +0 -108
  113. data/lib/droonga/plugin/input_adapter/groonga.rb +0 -49
  114. data/lib/droonga/plugin/input_adapter/groonga/select.rb +0 -63
  115. data/lib/droonga/plugin/output_adapter/crud.rb +0 -51
  116. data/lib/droonga/plugin/output_adapter/groonga/select.rb +0 -54
  117. data/lib/groonga_command_converter.rb +0 -143
  118. data/sample/fluentd.conf +0 -8
  119. data/test/unit/plugin/distributor/test_search_planner.rb +0 -1102
  120. data/test/unit/plugin/input_adapter/groonga/test_select.rb +0 -248
  121. data/test/unit/test_command_mapper.rb +0 -44
  122. data/test/unit/test_groonga_command_converter.rb +0 -242
@@ -0,0 +1,388 @@
1
+ # Copyright (C) 2013-2014 Droonga Project
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 version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ class DistributedSearchPlannerOutputTest < Test::Unit::TestCase
17
+ include DistributedSearchPlannerHelper
18
+
19
+ class NoOutputTest < self
20
+ def setup
21
+ @request = {
22
+ "type" => "search",
23
+ "dataset" => "Droonga",
24
+ "body" => {
25
+ "queries" => {
26
+ "users" => {
27
+ "source" => "User",
28
+ },
29
+ },
30
+ },
31
+ }
32
+ end
33
+
34
+ def test_dependencies
35
+ reduce_inputs = ["errors"]
36
+ gather_inputs = ["errors_reduced"]
37
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
38
+ dependencies)
39
+ end
40
+
41
+ def test_broadcast_body
42
+ assert_equal({
43
+ "queries" => {
44
+ "users" => {
45
+ "source" => "User",
46
+ },
47
+ },
48
+ },
49
+ broadcast_message["body"])
50
+ end
51
+ end
52
+
53
+ class NoLimitTest < self
54
+ def setup
55
+ @request = {
56
+ "type" => "search",
57
+ "dataset" => "Droonga",
58
+ "body" => {
59
+ "queries" => {
60
+ "users" => {
61
+ "source" => "User",
62
+ "output" => {
63
+ "format" => "complex",
64
+ "elements" => ["count", "records"],
65
+ },
66
+ },
67
+ },
68
+ },
69
+ }
70
+ end
71
+
72
+ def test_dependencies
73
+ reduce_inputs = ["errors", "users"]
74
+ gather_inputs = ["errors_reduced", "users_reduced"]
75
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
76
+ dependencies)
77
+ end
78
+
79
+ def test_broadcast_body
80
+ assert_equal({
81
+ "queries" => {
82
+ "users" => {
83
+ "source" => "User",
84
+ "output" => {
85
+ "format" => "simple",
86
+ "elements" => ["count", "records"],
87
+ },
88
+ },
89
+ },
90
+ },
91
+ broadcast_message["body"])
92
+ end
93
+
94
+ def test_reduce_body
95
+ assert_equal({
96
+ "users_reduced" => {
97
+ "count" => {
98
+ "type" => "sum",
99
+ },
100
+ },
101
+ },
102
+ reduce_message["body"]["users"])
103
+ end
104
+
105
+ def test_gather_body
106
+ assert_equal({
107
+ "output" => "users",
108
+ },
109
+ gather_message["body"]["users_reduced"])
110
+ end
111
+ end
112
+
113
+ class ElementsTest < self
114
+ class CountTest < self
115
+ def setup
116
+ @request = {
117
+ "type" => "search",
118
+ "dataset" => "Droonga",
119
+ "body" => {
120
+ "queries" => {
121
+ "users" => {
122
+ "source" => "User",
123
+ "output" => {
124
+ "elements" => ["count"],
125
+ },
126
+ },
127
+ },
128
+ },
129
+ }
130
+ end
131
+
132
+ def test_dependencies
133
+ reduce_inputs = ["errors", "users"]
134
+ gather_inputs = ["errors_reduced", "users_reduced"]
135
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
136
+ dependencies)
137
+ end
138
+
139
+ def test_broadcast_body
140
+ assert_equal({
141
+ "queries" => {
142
+ "users" => {
143
+ "output" => {
144
+ "elements" => ["count"],
145
+ },
146
+ "source" => "User",
147
+ },
148
+ },
149
+ },
150
+ broadcast_message["body"])
151
+ end
152
+
153
+ def test_reduce_body
154
+ assert_equal({
155
+ "users_reduced" => {
156
+ "count" => {
157
+ "type" => "sum",
158
+ },
159
+ },
160
+ },
161
+ reduce_message["body"]["users"])
162
+ end
163
+
164
+ def test_gather_body
165
+ assert_equal({
166
+ "output" => "users",
167
+ },
168
+ gather_message["body"]["users_reduced"])
169
+ end
170
+ end
171
+
172
+ class RecordsTest < self
173
+ def setup
174
+ @request = {
175
+ "type" => "search",
176
+ "dataset" => "Droonga",
177
+ "body" => {
178
+ "queries" => {
179
+ "users" => {
180
+ "source" => "User",
181
+ "output" => {
182
+ "elements" => ["records"],
183
+ "attributes" => ["_key"],
184
+ "limit" => 1,
185
+ },
186
+ },
187
+ },
188
+ },
189
+ }
190
+ end
191
+
192
+ def test_dependencies
193
+ reduce_inputs = ["errors", "users"]
194
+ gather_inputs = ["errors_reduced", "users_reduced"]
195
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
196
+ dependencies)
197
+ end
198
+
199
+ def test_broadcast_body
200
+ assert_equal({
201
+ "queries" => {
202
+ "users" => {
203
+ "output" => {
204
+ "elements" => ["records"],
205
+ "attributes" => ["_key"],
206
+ "limit" => 1,
207
+ },
208
+ "source" => "User",
209
+ },
210
+ },
211
+ },
212
+ broadcast_message["body"])
213
+ end
214
+
215
+ def test_reduce_body
216
+ assert_equal({
217
+ "users_reduced" => {
218
+ "records" => {
219
+ "type" => "sort",
220
+ "operators" => [],
221
+ "limit" => 1,
222
+ },
223
+ },
224
+ },
225
+ reduce_message["body"]["users"])
226
+ end
227
+
228
+ def test_gather_body
229
+ assert_equal({
230
+ "elements" => {
231
+ "records" => {
232
+ "attributes" => ["_key"],
233
+ "limit" => 1,
234
+ },
235
+ },
236
+ "output" => "users",
237
+ },
238
+ gather_message["body"]["users_reduced"])
239
+ end
240
+ end
241
+ end
242
+
243
+ class FormatTest < self
244
+ def setup
245
+ @output = {
246
+ "format" => "complex",
247
+ "elements" => ["records"],
248
+ "attributes" => ["_id"],
249
+ "offset" => 0,
250
+ "limit" => 10,
251
+ }
252
+ @request = {
253
+ "type" => "search",
254
+ "dataset" => "Droonga",
255
+ "body" => {
256
+ "queries" => {
257
+ "users" => {
258
+ "source" => "User",
259
+ "output" => @output,
260
+ },
261
+ },
262
+ },
263
+ }
264
+ end
265
+
266
+ def test_dependencies
267
+ reduce_inputs = ["errors", "users"]
268
+ gather_inputs = ["errors_reduced", "users_reduced"]
269
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
270
+ dependencies)
271
+ end
272
+
273
+ def test_broadcast_body
274
+ changed_output_parameters = {
275
+ "format" => "simple",
276
+ }
277
+ assert_equal({
278
+ "queries" => {
279
+ "users" => {
280
+ "source" => "User",
281
+ "output" => @output.merge(changed_output_parameters),
282
+ },
283
+ },
284
+ },
285
+ broadcast_message["body"])
286
+ end
287
+
288
+ def test_reduce_body
289
+ assert_equal({
290
+ "users_reduced" => {
291
+ "records" => {
292
+ "type" => "sort",
293
+ "operators" => [],
294
+ "limit" => 10,
295
+ },
296
+ },
297
+ },
298
+ reduce_message["body"]["users"])
299
+ end
300
+
301
+ def test_gather_records
302
+ assert_equal({
303
+ "elements" => {
304
+ "records" => {
305
+ "format" => "complex",
306
+ "attributes" => ["_id"],
307
+ "limit" => 10,
308
+ },
309
+ },
310
+ "output" => "users",
311
+ },
312
+ gather_message["body"]["users_reduced"])
313
+ end
314
+ end
315
+
316
+ class OffsetTest < self
317
+ def setup
318
+ @output = {
319
+ "elements" => ["records"],
320
+ "attributes" => ["_key"],
321
+ "offset" => 1,
322
+ "limit" => 1,
323
+ }
324
+ @request = {
325
+ "type" => "search",
326
+ "dataset" => "Droonga",
327
+ "body" => {
328
+ "queries" => {
329
+ "users" => {
330
+ "source" => "User",
331
+ "output" => @output,
332
+ },
333
+ },
334
+ },
335
+ }
336
+ end
337
+
338
+ def test_dependencies
339
+ reduce_inputs = ["errors", "users"]
340
+ gather_inputs = ["errors_reduced", "users_reduced"]
341
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
342
+ dependencies)
343
+ end
344
+
345
+ def test_broadcast_body
346
+ changed_output_parameters = {
347
+ "offset" => 0,
348
+ "limit" => 2,
349
+ }
350
+ assert_equal({
351
+ "queries" => {
352
+ "users" => {
353
+ "source" => "User",
354
+ "output" => @output.merge(changed_output_parameters),
355
+ },
356
+ },
357
+ },
358
+ broadcast_message["body"])
359
+ end
360
+
361
+ def test_reduce_body
362
+ assert_equal({
363
+ "users_reduced" => {
364
+ "records" => {
365
+ "type" => "sort",
366
+ "operators" => [],
367
+ "limit" => 2,
368
+ },
369
+ },
370
+ },
371
+ reduce_message["body"]["users"])
372
+ end
373
+
374
+ def test_gather_records
375
+ assert_equal({
376
+ "elements" => {
377
+ "records" => {
378
+ "attributes" => ["_key"],
379
+ "offset" => 1,
380
+ "limit" => 1,
381
+ },
382
+ },
383
+ "output" => "users",
384
+ },
385
+ gather_message["body"]["users_reduced"])
386
+ end
387
+ end
388
+ end
@@ -0,0 +1,938 @@
1
+ # Copyright (C) 2013-2014 Droonga Project
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 version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ class DistributedSearchPlannerSortByTest < Test::Unit::TestCase
17
+ include DistributedSearchPlannerHelper
18
+
19
+ class SimpleTest < self
20
+ def setup
21
+ @output = {
22
+ "elements" => ["records"],
23
+ "attributes" => ["_key"],
24
+ "limit" => 1,
25
+ }
26
+ @request = {
27
+ "type" => "search",
28
+ "dataset" => "Droonga",
29
+ "body" => {
30
+ "queries" => {
31
+ "users" => {
32
+ "source" => "User",
33
+ "sortBy" => ["_key"],
34
+ "output" => @output,
35
+ },
36
+ },
37
+ },
38
+ }
39
+ end
40
+
41
+ def test_dependencies
42
+ reduce_inputs = ["errors", "users"]
43
+ gather_inputs = ["errors_reduced", "users_reduced"]
44
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
45
+ dependencies)
46
+ end
47
+
48
+ def test_broadcast_body
49
+ assert_equal({
50
+ "queries" => {
51
+ "users" => {
52
+ "source" => "User",
53
+ "sortBy" => ["_key"],
54
+ "output" => @output,
55
+ },
56
+ },
57
+ },
58
+ broadcast_message["body"])
59
+ end
60
+
61
+ def test_reduce_body
62
+ assert_equal({
63
+ "users_reduced" => {
64
+ "records" => {
65
+ "type" => "sort",
66
+ "operators" => [
67
+ { "column" => 0, "operator" => "<" },
68
+ ],
69
+ "limit" => 1,
70
+ },
71
+ },
72
+ },
73
+ reduce_message["body"]["users"])
74
+ end
75
+
76
+ def test_gather_records
77
+ assert_equal({
78
+ "elements" => {
79
+ "records" => {
80
+ "attributes" => ["_key"],
81
+ "limit" => 1,
82
+ },
83
+ },
84
+ "output" => "users",
85
+ },
86
+ gather_message["body"]["users_reduced"])
87
+ end
88
+ end
89
+
90
+ class SimpleHiddenColumnTest < self
91
+ def setup
92
+ @output = {
93
+ "elements" => ["records"],
94
+ "attributes" => ["_key"],
95
+ "limit" => 1,
96
+ }
97
+ @request = {
98
+ "type" => "search",
99
+ "dataset" => "Droonga",
100
+ "body" => {
101
+ "queries" => {
102
+ "users" => {
103
+ "source" => "User",
104
+ "sortBy" => ["name"],
105
+ "output" => @output,
106
+ },
107
+ },
108
+ },
109
+ }
110
+ end
111
+
112
+ def test_dependencies
113
+ reduce_inputs = ["errors", "users"]
114
+ gather_inputs = ["errors_reduced", "users_reduced"]
115
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
116
+ dependencies)
117
+ end
118
+
119
+ def test_broadcast_body
120
+ changed_output_parameters = {
121
+ "attributes" => ["_key", "name"],
122
+ }
123
+ assert_equal({
124
+ "queries" => {
125
+ "users" => {
126
+ "source" => "User",
127
+ "sortBy" => ["name"],
128
+ "output" => @output.merge(changed_output_parameters),
129
+ },
130
+ },
131
+ },
132
+ broadcast_message["body"])
133
+ end
134
+
135
+ def test_reduce_body
136
+ assert_equal({
137
+ "users_reduced" => {
138
+ "records" => {
139
+ "type" => "sort",
140
+ "operators" => [
141
+ { "column" => 1, "operator" => "<" },
142
+ ],
143
+ "limit" => 1,
144
+ },
145
+ },
146
+ },
147
+ reduce_message["body"]["users"])
148
+ end
149
+
150
+ def test_gather_records
151
+ assert_equal({
152
+ "elements" => {
153
+ "records" => {
154
+ "attributes" => ["_key"],
155
+ "limit" => 1,
156
+ },
157
+ },
158
+ "output" => "users",
159
+ },
160
+ gather_message["body"]["users_reduced"])
161
+ end
162
+ end
163
+
164
+ class ComplexTest < self
165
+ def setup
166
+ @output = {
167
+ "elements" => ["records"],
168
+ "attributes" => ["_key"],
169
+ "limit" => 1,
170
+ }
171
+ @sort_by = {
172
+ "keys" => ["_key"],
173
+ }
174
+ @request = {
175
+ "type" => "search",
176
+ "dataset" => "Droonga",
177
+ "body" => {
178
+ "queries" => {
179
+ "users" => {
180
+ "source" => "User",
181
+ "sortBy" => @sort_by,
182
+ "output" => @output,
183
+ },
184
+ },
185
+ },
186
+ }
187
+ end
188
+
189
+ def test_dependencies
190
+ reduce_inputs = ["errors", "users"]
191
+ gather_inputs = ["errors_reduced", "users_reduced"]
192
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
193
+ dependencies)
194
+ end
195
+
196
+ def test_broadcast_body
197
+ changed_sort_by_parameters = {
198
+ "offset" => 0,
199
+ "limit" => 1,
200
+ }
201
+ assert_equal({
202
+ "queries" => {
203
+ "users" => {
204
+ "source" => "User",
205
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
206
+ "output" => @output,
207
+ },
208
+ },
209
+ },
210
+ broadcast_message["body"])
211
+ end
212
+
213
+ def test_reduce_body
214
+ assert_equal({
215
+ "users_reduced" => {
216
+ "records" => {
217
+ "type" => "sort",
218
+ "operators" => [
219
+ { "column" => 0, "operator" => "<" },
220
+ ],
221
+ "limit" => 1,
222
+ },
223
+ },
224
+ },
225
+ reduce_message["body"]["users"])
226
+ end
227
+
228
+ def test_gather_records
229
+ assert_equal({
230
+ "elements" => {
231
+ "records" => {
232
+ "attributes" => ["_key"],
233
+ "limit" => 1,
234
+ },
235
+ },
236
+ "output" => "users",
237
+ },
238
+ gather_message["body"]["users_reduced"])
239
+ end
240
+ end
241
+
242
+ class ComplexHiddenColumnTest < self
243
+ def setup
244
+ @output = {
245
+ "elements" => ["records"],
246
+ "attributes" => ["_key"],
247
+ "limit" => 1,
248
+ }
249
+ @sort_by = {
250
+ "keys" => ["name"],
251
+ }
252
+ @request = {
253
+ "type" => "search",
254
+ "dataset" => "Droonga",
255
+ "body" => {
256
+ "queries" => {
257
+ "users" => {
258
+ "source" => "User",
259
+ "sortBy" => @sort_by,
260
+ "output" => @output,
261
+ },
262
+ },
263
+ },
264
+ }
265
+ end
266
+
267
+ def test_dependencies
268
+ reduce_inputs = ["errors", "users"]
269
+ gather_inputs = ["errors_reduced", "users_reduced"]
270
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
271
+ dependencies)
272
+ end
273
+
274
+ def test_broadcast_body
275
+ changed_sort_by_parameters = {
276
+ "offset" => 0,
277
+ "limit" => 1,
278
+ }
279
+ changed_output_parameters = {
280
+ "attributes" => ["_key", "name"],
281
+ }
282
+ assert_equal({
283
+ "queries" => {
284
+ "users" => {
285
+ "source" => "User",
286
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
287
+ "output" => @output.merge(changed_output_parameters),
288
+ },
289
+ },
290
+ },
291
+ broadcast_message["body"])
292
+ end
293
+
294
+ def test_reduce_body
295
+ assert_equal({
296
+ "users_reduced" => {
297
+ "records" => {
298
+ "type" => "sort",
299
+ "operators" => [
300
+ { "column" => 1, "operator" => "<" },
301
+ ],
302
+ "limit" => 1,
303
+ },
304
+ },
305
+ },
306
+ reduce_message["body"]["users"])
307
+ end
308
+
309
+ def test_gather_records
310
+ assert_equal({
311
+ "elements" => {
312
+ "records" => {
313
+ "attributes" => ["_key"],
314
+ "limit" => 1,
315
+ },
316
+ },
317
+ "output" => "users",
318
+ },
319
+ gather_message["body"]["users_reduced"])
320
+ end
321
+ end
322
+
323
+ class WithHashAttributesTest < self
324
+ def setup
325
+ @output = {
326
+ "elements" => ["records"],
327
+ "attributes" => {
328
+ "id" => "_key",
329
+ "name" => { "source" => "name" },
330
+ },
331
+ "limit" => 1,
332
+ }
333
+ @sort_by = {
334
+ "keys" => ["hidden"],
335
+ }
336
+ @request = {
337
+ "type" => "search",
338
+ "dataset" => "Droonga",
339
+ "body" => {
340
+ "queries" => {
341
+ "users" => {
342
+ "source" => "User",
343
+ "sortBy" => @sort_by,
344
+ "output" => @output,
345
+ },
346
+ },
347
+ },
348
+ }
349
+ end
350
+
351
+ def test_dependencies
352
+ reduce_inputs = ["errors", "users"]
353
+ gather_inputs = ["errors_reduced", "users_reduced"]
354
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
355
+ dependencies)
356
+ end
357
+
358
+ def test_broadcast_body
359
+ changed_sort_by_parameters = {
360
+ "offset" => 0,
361
+ "limit" => 1,
362
+ }
363
+ changed_output_parameters = {
364
+ "attributes" => [
365
+ { "label" => "id", "source" => "_key" },
366
+ { "label" => "name", "source" => "name" },
367
+ "hidden",
368
+ ],
369
+ }
370
+ assert_equal({
371
+ "queries" => {
372
+ "users" => {
373
+ "source" => "User",
374
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
375
+ "output" => @output.merge(changed_output_parameters),
376
+ },
377
+ },
378
+ },
379
+ broadcast_message["body"])
380
+ end
381
+
382
+ def test_reduce_body
383
+ assert_equal({
384
+ "users_reduced" => {
385
+ "records" => {
386
+ "type" => "sort",
387
+ "operators" => [
388
+ { "column" => 2, "operator" => "<" },
389
+ ],
390
+ "limit" => 1,
391
+ },
392
+ },
393
+ },
394
+ reduce_message["body"]["users"])
395
+ end
396
+
397
+ def test_gather_records
398
+ assert_equal({
399
+ "elements" => {
400
+ "records" => {
401
+ "attributes" => ["id", "name"],
402
+ "limit" => 1,
403
+ },
404
+ },
405
+ "output" => "users",
406
+ },
407
+ gather_message["body"]["users_reduced"])
408
+ end
409
+ end
410
+
411
+ class WithComplexAttributesArrayTest < self
412
+ def setup
413
+ @output = {
414
+ "elements" => ["records"],
415
+ "attributes" => [
416
+ { "label" => "id", "source" => "_key" },
417
+ { "label" => "real_name", "source" => "name" },
418
+ ],
419
+ "limit" => 1,
420
+ }
421
+ @sort_by = {
422
+ "keys" => ["name"],
423
+ }
424
+ @request = {
425
+ "type" => "search",
426
+ "dataset" => "Droonga",
427
+ "body" => {
428
+ "queries" => {
429
+ "users" => {
430
+ "source" => "User",
431
+ "sortBy" => @sort_by,
432
+ "output" => @output,
433
+ },
434
+ },
435
+ },
436
+ }
437
+ end
438
+
439
+ def test_dependencies
440
+ reduce_inputs = ["errors", "users"]
441
+ gather_inputs = ["errors_reduced", "users_reduced"]
442
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
443
+ dependencies)
444
+ end
445
+
446
+ def test_broadcast_body
447
+ changed_sort_by_parameters = {
448
+ "offset" => 0,
449
+ "limit" => 1,
450
+ }
451
+ changed_output_parameters = {
452
+ "attributes" => [
453
+ { "label" => "id", "source" => "_key" },
454
+ { "label" => "real_name", "source" => "name" },
455
+ ],
456
+ }
457
+ assert_equal({
458
+ "queries" => {
459
+ "users" => {
460
+ "source" => "User",
461
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
462
+ "output" => @output.merge(changed_output_parameters),
463
+ },
464
+ },
465
+ },
466
+ broadcast_message["body"])
467
+ end
468
+
469
+ def test_reduce_body
470
+ assert_equal({
471
+ "users_reduced" => {
472
+ "records" => {
473
+ "type" => "sort",
474
+ "operators" => [
475
+ { "column" => 1, "operator" => "<" },
476
+ ],
477
+ "limit" => 1,
478
+ },
479
+ },
480
+ },
481
+ reduce_message["body"]["users"])
482
+ end
483
+
484
+ def test_gather_records
485
+ assert_equal({
486
+ "elements" => {
487
+ "records" => {
488
+ "attributes" => ["id", "real_name"],
489
+ "limit" => 1,
490
+ },
491
+ },
492
+ "output" => "users",
493
+ },
494
+ gather_message["body"]["users_reduced"])
495
+ end
496
+ end
497
+
498
+ class MultipleColumnsTest < self
499
+ def setup
500
+ @output = {
501
+ "elements" => ["records"],
502
+ "attributes" => ["_key"],
503
+ "limit" => 1,
504
+ }
505
+ @sort_by = {
506
+ "keys" => ["-age", "name", "_key"],
507
+ }
508
+ @request = {
509
+ "type" => "search",
510
+ "dataset" => "Droonga",
511
+ "body" => {
512
+ "queries" => {
513
+ "users" => {
514
+ "source" => "User",
515
+ "sortBy" => @sort_by,
516
+ "output" => @output,
517
+ },
518
+ },
519
+ },
520
+ }
521
+ end
522
+
523
+ def test_dependencies
524
+ reduce_inputs = ["errors", "users"]
525
+ gather_inputs = ["errors_reduced", "users_reduced"]
526
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
527
+ dependencies)
528
+ end
529
+
530
+ def test_broadcast_body
531
+ changed_sort_by_parameters = {
532
+ "offset" => 0,
533
+ "limit" => 1,
534
+ }
535
+ changed_output_parameters = {
536
+ "attributes" => ["_key", "age", "name"],
537
+ }
538
+ assert_equal({
539
+ "queries" => {
540
+ "users" => {
541
+ "source" => "User",
542
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
543
+ "output" => @output.merge(changed_output_parameters),
544
+ },
545
+ },
546
+ },
547
+ broadcast_message["body"])
548
+ end
549
+
550
+ def test_reduce_body
551
+ assert_equal({
552
+ "users_reduced" => {
553
+ "records" => {
554
+ "type" => "sort",
555
+ "operators" => [
556
+ { "column" => 1, "operator" => ">" },
557
+ { "column" => 2, "operator" => "<" },
558
+ { "column" => 0, "operator" => "<" },
559
+ ],
560
+ "limit" => 1,
561
+ },
562
+ },
563
+ },
564
+ reduce_message["body"]["users"])
565
+ end
566
+
567
+ def test_gather_records
568
+ assert_equal({
569
+ "elements" => {
570
+ "records" => {
571
+ "attributes" => ["_key"],
572
+ "limit" => 1,
573
+ },
574
+ },
575
+ "output" => "users",
576
+ },
577
+ gather_message["body"]["users_reduced"])
578
+ end
579
+ end
580
+
581
+ class OffsetLimitTest < self
582
+ def max_limit
583
+ [@sort_by["limit"], @output["limit"]].max
584
+ end
585
+
586
+ def min_limit
587
+ [@sort_by["limit"], @output["limit"]].min
588
+ end
589
+
590
+ def total_offset
591
+ @sort_by["offset"] + @output["offset"]
592
+ end
593
+
594
+ class RegularRangeTest < self
595
+ def setup
596
+ @output = {
597
+ "elements" => ["records"],
598
+ "attributes" => ["_key"],
599
+ "offset" => 4,
600
+ "limit" => 8,
601
+ }
602
+ @sort_by = {
603
+ "keys" => ["_key"],
604
+ "offset" => 1,
605
+ "limit" => 2,
606
+ }
607
+ @request = {
608
+ "type" => "search",
609
+ "dataset" => "Droonga",
610
+ "body" => {
611
+ "queries" => {
612
+ "users" => {
613
+ "source" => "User",
614
+ "sortBy" => @sort_by,
615
+ "output" => @output,
616
+ },
617
+ },
618
+ },
619
+ }
620
+ end
621
+
622
+ def test_dependencies
623
+ reduce_inputs = ["errors", "users"]
624
+ gather_inputs = ["errors_reduced", "users_reduced"]
625
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
626
+ dependencies)
627
+ end
628
+
629
+ def test_broadcast_body
630
+ changed_sort_by_parameters = {
631
+ "offset" => 0,
632
+ "limit" => total_offset + max_limit,
633
+ }
634
+ changed_output_parameters = {
635
+ "offset" => 0,
636
+ "limit" => total_offset + min_limit,
637
+ }
638
+ assert_equal({
639
+ "queries" => {
640
+ "users" => {
641
+ "source" => "User",
642
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
643
+ "output" => @output.merge(changed_output_parameters),
644
+ },
645
+ },
646
+ },
647
+ broadcast_message["body"])
648
+ end
649
+
650
+ def test_reduce_body
651
+ assert_equal({
652
+ "users_reduced" => {
653
+ "records" => {
654
+ "type" => "sort",
655
+ "operators" => [
656
+ { "column" => 0, "operator" => "<" },
657
+ ],
658
+ "limit" => total_offset + min_limit,
659
+ },
660
+ },
661
+ },
662
+ reduce_message["body"]["users"])
663
+ end
664
+
665
+ def test_gather_records
666
+ assert_equal({
667
+ "elements" => {
668
+ "records" => {
669
+ "attributes" => ["_key"],
670
+ "offset" => total_offset,
671
+ "limit" => min_limit,
672
+ },
673
+ },
674
+ "output" => "users",
675
+ },
676
+ gather_message["body"]["users_reduced"])
677
+ end
678
+ end
679
+
680
+ class InfinitOutputLimitTest < self
681
+ def setup
682
+ @output = {
683
+ "elements" => ["records"],
684
+ "attributes" => ["_key"],
685
+ "offset" => 4,
686
+ "limit" => -1,
687
+ }
688
+ @sort_by = {
689
+ "keys" => ["_key"],
690
+ "offset" => 1,
691
+ "limit" => 2,
692
+ }
693
+ @request = {
694
+ "type" => "search",
695
+ "dataset" => "Droonga",
696
+ "body" => {
697
+ "queries" => {
698
+ "users" => {
699
+ "source" => "User",
700
+ "sortBy" => @sort_by,
701
+ "output" => @output,
702
+ },
703
+ },
704
+ },
705
+ }
706
+ end
707
+
708
+ def test_dependencies
709
+ reduce_inputs = ["errors", "users"]
710
+ gather_inputs = ["errors_reduced", "users_reduced"]
711
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
712
+ dependencies)
713
+ end
714
+
715
+ def test_broadcast_body
716
+ changed_sort_by_parameters = {
717
+ "offset" => 0,
718
+ "limit" => total_offset + max_limit,
719
+ }
720
+ changed_output_parameters = {
721
+ "offset" => 0,
722
+ "limit" => total_offset + max_limit,
723
+ }
724
+ assert_equal({
725
+ "queries" => {
726
+ "users" => {
727
+ "source" => "User",
728
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
729
+ "output" => @output.merge(changed_output_parameters),
730
+ },
731
+ },
732
+ },
733
+ broadcast_message["body"])
734
+ end
735
+
736
+ def test_reduce_body
737
+ assert_equal({
738
+ "users_reduced" => {
739
+ "records" => {
740
+ "type" => "sort",
741
+ "operators" => [
742
+ { "column" => 0, "operator" => "<" },
743
+ ],
744
+ "limit" => total_offset + max_limit,
745
+ },
746
+ },
747
+ },
748
+ reduce_message["body"]["users"])
749
+ end
750
+
751
+ def test_gather_records
752
+ assert_equal({
753
+ "elements" => {
754
+ "records" => {
755
+ "attributes" => ["_key"],
756
+ "offset" => total_offset,
757
+ "limit" => max_limit,
758
+ },
759
+ },
760
+ "output" => "users",
761
+ },
762
+ gather_message["body"]["users_reduced"])
763
+ end
764
+ end
765
+
766
+ class InifinitSortLimitTest < self
767
+ def setup
768
+ @output = {
769
+ "elements" => ["records"],
770
+ "attributes" => ["_key"],
771
+ "offset" => 4,
772
+ "limit" => 8,
773
+ }
774
+ @sort_by = {
775
+ "keys" => ["_key"],
776
+ "offset" => 1,
777
+ "limit" => -1,
778
+ }
779
+ @request = {
780
+ "type" => "search",
781
+ "dataset" => "Droonga",
782
+ "body" => {
783
+ "queries" => {
784
+ "users" => {
785
+ "source" => "User",
786
+ "sortBy" => @sort_by,
787
+ "output" => @output,
788
+ },
789
+ },
790
+ },
791
+ }
792
+ end
793
+
794
+ def test_dependencies
795
+ reduce_inputs = ["errors", "users"]
796
+ gather_inputs = ["errors_reduced", "users_reduced"]
797
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
798
+ dependencies)
799
+ end
800
+
801
+ def test_broadcast_body
802
+ changed_sort_by_parameters = {
803
+ "offset" => 0,
804
+ "limit" => total_offset + max_limit,
805
+ }
806
+ changed_output_parameters = {
807
+ "offset" => 0,
808
+ "limit" => total_offset + max_limit,
809
+ }
810
+ assert_equal({
811
+ "queries" => {
812
+ "users" => {
813
+ "source" => "User",
814
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
815
+ "output" => @output.merge(changed_output_parameters),
816
+ },
817
+ },
818
+ },
819
+ broadcast_message["body"])
820
+ end
821
+
822
+ def test_reduce_body
823
+ assert_equal({
824
+ "users_reduced" => {
825
+ "records" => {
826
+ "type" => "sort",
827
+ "operators" => [
828
+ { "column" => 0, "operator" => "<" },
829
+ ],
830
+ "limit" => total_offset + max_limit,
831
+ },
832
+ },
833
+ },
834
+ reduce_message["body"]["users"])
835
+ end
836
+
837
+ def test_gather_records
838
+ assert_equal({
839
+ "elements" => {
840
+ "records" => {
841
+ "attributes" => ["_key"],
842
+ "offset" => total_offset,
843
+ "limit" => max_limit,
844
+ },
845
+ },
846
+ "output" => "users",
847
+ },
848
+ gather_message["body"]["users_reduced"])
849
+ end
850
+ end
851
+
852
+ class InifinitBothLimitTest < self
853
+ def setup
854
+ @output = {
855
+ "elements" => ["records"],
856
+ "attributes" => ["_key"],
857
+ "offset" => 4,
858
+ "limit" => -1,
859
+ }
860
+ @sort_by = {
861
+ "keys" => ["_key"],
862
+ "offset" => 1,
863
+ "limit" => -1,
864
+ }
865
+ @request = {
866
+ "type" => "search",
867
+ "dataset" => "Droonga",
868
+ "body" => {
869
+ "queries" => {
870
+ "users" => {
871
+ "source" => "User",
872
+ "sortBy" => @sort_by,
873
+ "output" => @output,
874
+ },
875
+ },
876
+ },
877
+ }
878
+ end
879
+
880
+ def test_dependencies
881
+ reduce_inputs = ["errors", "users"]
882
+ gather_inputs = ["errors_reduced", "users_reduced"]
883
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
884
+ dependencies)
885
+ end
886
+
887
+ def test_broadcast_body
888
+ changed_sort_by_parameters = {
889
+ "offset" => 0,
890
+ "limit" => min_limit,
891
+ }
892
+ changed_output_parameters = {
893
+ "offset" => 0,
894
+ "limit" => min_limit,
895
+ }
896
+ assert_equal({
897
+ "queries" => {
898
+ "users" => {
899
+ "source" => "User",
900
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
901
+ "output" => @output.merge(changed_output_parameters),
902
+ },
903
+ },
904
+ },
905
+ broadcast_message["body"])
906
+ end
907
+
908
+ def test_reduce_body
909
+ assert_equal({
910
+ "users_reduced" => {
911
+ "records" => {
912
+ "type" => "sort",
913
+ "operators" => [
914
+ { "column" => 0, "operator" => "<" },
915
+ ],
916
+ "limit" => min_limit,
917
+ },
918
+ },
919
+ },
920
+ reduce_message["body"]["users"])
921
+ end
922
+
923
+ def test_gather_records
924
+ assert_equal({
925
+ "elements" => {
926
+ "records" => {
927
+ "attributes" => ["_key"],
928
+ "offset" => total_offset,
929
+ "limit" => min_limit,
930
+ },
931
+ },
932
+ "output" => "users",
933
+ },
934
+ gather_message["body"]["users_reduced"])
935
+ end
936
+ end
937
+ end
938
+ end