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
@@ -87,7 +87,7 @@ class SearchCollectorTest < Test::Unit::TestCase
87
87
  "output" => "search_result",
88
88
  "elements" => {
89
89
  "records" => {
90
- "type" => "sort",
90
+ "attributes" => ["_key"],
91
91
  "offset" => 1,
92
92
  "limit" => 1,
93
93
  },
@@ -114,7 +114,7 @@ class SearchCollectorTest < Test::Unit::TestCase
114
114
  "output" => "search_result",
115
115
  "elements" => {
116
116
  "records" => {
117
- "type" => "sort",
117
+ "attributes" => ["_key"],
118
118
  "offset" => 1,
119
119
  "limit" => -1,
120
120
  },
@@ -138,7 +138,6 @@ class SearchCollectorTest < Test::Unit::TestCase
138
138
  "output" => "search_result",
139
139
  "elements" => {
140
140
  "records" => {
141
- "type" => "sort",
142
141
  "format" => "simple",
143
142
  "attributes" => [],
144
143
  "offset" => 10000,
@@ -166,7 +165,6 @@ class SearchCollectorTest < Test::Unit::TestCase
166
165
  "output" => "search_result",
167
166
  "elements" => {
168
167
  "records" => {
169
- "type" => "sort",
170
168
  "attributes" => ["_key", "chapter", "section", "subsection", "paragraph"],
171
169
  "limit" => -1,
172
170
  },
@@ -192,7 +190,6 @@ class SearchCollectorTest < Test::Unit::TestCase
192
190
  "output" => "search_result",
193
191
  "elements" => {
194
192
  "records" => {
195
- "type" => "sort",
196
193
  "attributes" => ["_key", "chapter", "section"],
197
194
  "limit" => -1,
198
195
  },
@@ -218,7 +215,6 @@ class SearchCollectorTest < Test::Unit::TestCase
218
215
  "output" => "search_result",
219
216
  "elements" => {
220
217
  "records" => {
221
- "type" => "sort",
222
218
  "format" => "simple",
223
219
  "attributes" => ["_key", "chapter", "section"],
224
220
  "limit" => -1,
@@ -245,7 +241,6 @@ class SearchCollectorTest < Test::Unit::TestCase
245
241
  "output" => "search_result",
246
242
  "elements" => {
247
243
  "records" => {
248
- "type" => "sort",
249
244
  "format" => "complex",
250
245
  "attributes" => ["_key", "chapter", "section"],
251
246
  "limit" => -1,
@@ -272,11 +267,9 @@ class SearchCollectorTest < Test::Unit::TestCase
272
267
  "output" => "search_result",
273
268
  "elements" => {
274
269
  "count" => {
275
- "type" => "count",
276
270
  "target" => "records",
277
271
  },
278
272
  "records" => {
279
- "type" => "sort",
280
273
  "format" => "simple",
281
274
  "attributes" => [],
282
275
  "limit" => -1,
@@ -299,11 +292,9 @@ class SearchCollectorTest < Test::Unit::TestCase
299
292
  "output" => "search_result",
300
293
  "elements" => {
301
294
  "count" => {
302
- "type" => "count",
303
295
  "target" => "records",
304
296
  },
305
297
  "records" => {
306
- "type" => "sort",
307
298
  "format" => "simple",
308
299
  "attributes" => [],
309
300
  "limit" => -1,
@@ -317,7 +308,7 @@ class SearchCollectorTest < Test::Unit::TestCase
317
308
  request = {
318
309
  "task" => {
319
310
  "values" => nil,
320
- "component" => {
311
+ "step" => {
321
312
  "body" => nil,
322
313
  "outputs" => nil,
323
314
  },
@@ -355,7 +346,7 @@ class SearchCollectorTest < Test::Unit::TestCase
355
346
  ],
356
347
  },
357
348
  },
358
- "component" => {
349
+ "step" => {
359
350
  "body" => {
360
351
  input_name => {
361
352
  output_name => {
@@ -440,7 +431,7 @@ class SearchCollectorTest < Test::Unit::TestCase
440
431
  ],
441
432
  },
442
433
  },
443
- "component" => {
434
+ "step" => {
444
435
  "body" => {
445
436
  input_name => {
446
437
  output_name => {
@@ -520,7 +511,7 @@ class SearchCollectorTest < Test::Unit::TestCase
520
511
  ],
521
512
  },
522
513
  },
523
- "component" => {
514
+ "step" => {
524
515
  "body" => {
525
516
  input_name => {
526
517
  output_name => {
@@ -604,7 +595,7 @@ class SearchCollectorTest < Test::Unit::TestCase
604
595
  ],
605
596
  },
606
597
  },
607
- "component" => {
598
+ "step" => {
608
599
  "body" => {
609
600
  input_name => {
610
601
  output_name => {
@@ -705,7 +696,7 @@ class SearchCollectorTest < Test::Unit::TestCase
705
696
  ],
706
697
  },
707
698
  },
708
- "component" => {
699
+ "step" => {
709
700
  "body" => {
710
701
  input_name => {
711
702
  output_name => {
@@ -0,0 +1,120 @@
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 DistributedSearchPlannerBasicTest < Test::Unit::TestCase
17
+ include DistributedSearchPlannerHelper
18
+
19
+ class MultipleQueriesTest < self
20
+ class MultipleOutputsTest < self
21
+ def setup
22
+ @request = {
23
+ "type" => "search",
24
+ "dataset" => "Droonga",
25
+ "body" => {
26
+ "queries" => {
27
+ "query1" => {
28
+ "source" => "User",
29
+ "output" => {
30
+ "elements" => ["count"],
31
+ },
32
+ },
33
+ "query2" => {
34
+ "source" => "User",
35
+ "output" => {
36
+ "elements" => ["count"],
37
+ },
38
+ },
39
+ },
40
+ },
41
+ }
42
+ end
43
+
44
+ def test_dependencies
45
+ reduce_inputs = [
46
+ "errors",
47
+ "query1",
48
+ "query2",
49
+ ]
50
+ gather_inputs = [
51
+ "errors_reduced",
52
+ "query1_reduced",
53
+ "query2_reduced",
54
+ ]
55
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
56
+ dependencies)
57
+ end
58
+ end
59
+ end
60
+
61
+ # this should be moved to the test for DistributedCommandPlanner
62
+ class BasicTest < self
63
+ def setup
64
+ @request = {
65
+ "type" => "search",
66
+ "dataset" => "Droonga",
67
+ "body" => {
68
+ "queries" => {
69
+ "no_output" => {
70
+ "source" => "User",
71
+ },
72
+ },
73
+ },
74
+ }
75
+ end
76
+
77
+ def test_dependencies
78
+ reduce_inputs = ["errors"]
79
+ gather_inputs = ["errors_reduced"]
80
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
81
+ dependencies)
82
+ end
83
+
84
+ def test_broadcast_message_metadata
85
+ message = broadcast_message
86
+ metadata = {
87
+ "command" => message["command"],
88
+ "dataset" => message["dataset"],
89
+ "replica" => message["replica"],
90
+ }
91
+ expected = {
92
+ "command" => @request["type"],
93
+ "dataset" => @request["dataset"],
94
+ "replica" => "random",
95
+ }
96
+ assert_equal(expected, metadata)
97
+ end
98
+
99
+ def test_reduce_body
100
+ assert_equal({
101
+ "errors" => {
102
+ "errors_reduced" => {
103
+ "type" => "sum",
104
+ "limit" => -1,
105
+ },
106
+ },
107
+ },
108
+ reduce_message["body"])
109
+ end
110
+
111
+ def test_gather_body
112
+ assert_equal({
113
+ "errors_reduced" => {
114
+ "output" => "errors",
115
+ },
116
+ },
117
+ gather_message["body"])
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,573 @@
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 DistributedSearchPlannerGroupByTest < Test::Unit::TestCase
17
+ include DistributedSearchPlannerHelper
18
+
19
+ class SimpleTest < self
20
+ def setup
21
+ @output = {
22
+ "elements" => ["records"],
23
+ "attributes" => ["_nsubrecs", "_key"],
24
+ "limit" => 1,
25
+ }
26
+ @group_by = "family_name"
27
+ @request = {
28
+ "type" => "search",
29
+ "dataset" => "Droonga",
30
+ "body" => {
31
+ "queries" => {
32
+ "families" => {
33
+ "source" => "User",
34
+ "groupBy" => @group_by,
35
+ "output" => @output,
36
+ },
37
+ },
38
+ },
39
+ }
40
+ end
41
+
42
+ def test_dependencies
43
+ reduce_inputs = ["errors", "families"]
44
+ gather_inputs = ["errors_reduced", "families_reduced"]
45
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
46
+ dependencies)
47
+ end
48
+
49
+ def test_broadcast_body
50
+ changed_output_parameters = {
51
+ "unifiable" => true,
52
+ }
53
+ assert_equal({
54
+ "queries" => {
55
+ "families" => {
56
+ "source" => "User",
57
+ "groupBy" => @group_by,
58
+ "output" => @output.merge(changed_output_parameters),
59
+ },
60
+ },
61
+ },
62
+ broadcast_message["body"])
63
+ end
64
+
65
+ def test_reduce_body
66
+ assert_equal({
67
+ "families_reduced" => {
68
+ "records" => {
69
+ "type" => "sort",
70
+ "operators" => [],
71
+ "key_column" => 1,
72
+ "limit" => 1,
73
+ },
74
+ },
75
+ },
76
+ reduce_message["body"]["families"])
77
+ end
78
+
79
+ def test_gather_records
80
+ assert_equal({
81
+ "elements" => {
82
+ "records" => {
83
+ "attributes" => ["_nsubrecs", "_key"],
84
+ "limit" => 1,
85
+ },
86
+ },
87
+ "output" => "families",
88
+ },
89
+ gather_message["body"]["families_reduced"])
90
+ end
91
+ end
92
+
93
+ class WithHashAttributesTest < self
94
+ def setup
95
+ @output = {
96
+ "elements" => ["records"],
97
+ "attributes" => {
98
+ "family_name" => "_key",
99
+ "count" => { "source" => "_nsubrecs" },
100
+ },
101
+ "limit" => 1,
102
+ }
103
+ @group_by = "family_name"
104
+ @request = {
105
+ "type" => "search",
106
+ "dataset" => "Droonga",
107
+ "body" => {
108
+ "queries" => {
109
+ "families" => {
110
+ "source" => "User",
111
+ "groupBy" => @group_by,
112
+ "output" => @output,
113
+ },
114
+ },
115
+ },
116
+ }
117
+ end
118
+
119
+ def test_dependencies
120
+ reduce_inputs = ["errors", "families"]
121
+ gather_inputs = ["errors_reduced", "families_reduced"]
122
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
123
+ dependencies)
124
+ end
125
+
126
+ def test_broadcast_body
127
+ changed_output_parameters = {
128
+ "attributes" => [
129
+ { "label" => "family_name", "source" => "_key" },
130
+ { "label" => "count", "source" => "_nsubrecs" },
131
+ ],
132
+ "unifiable" => true,
133
+ }
134
+ assert_equal({
135
+ "queries" => {
136
+ "families" => {
137
+ "source" => "User",
138
+ "groupBy" => @group_by,
139
+ "output" => @output.merge(changed_output_parameters),
140
+ },
141
+ },
142
+ },
143
+ broadcast_message["body"])
144
+ end
145
+
146
+ def test_reduce_body
147
+ assert_equal({
148
+ "families_reduced" => {
149
+ "records" => {
150
+ "type" => "sort",
151
+ "operators" => [],
152
+ "key_column" => 0,
153
+ "limit" => 1,
154
+ },
155
+ },
156
+ },
157
+ reduce_message["body"]["families"])
158
+ end
159
+
160
+ def test_gather_records
161
+ assert_equal({
162
+ "elements" => {
163
+ "records" => {
164
+ "attributes" => ["family_name", "count"],
165
+ "limit" => 1,
166
+ },
167
+ },
168
+ "output" => "families",
169
+ },
170
+ gather_message["body"]["families_reduced"])
171
+ end
172
+ end
173
+
174
+ class WithHashAttributesMissingKeyTest < self
175
+ def setup
176
+ @output = {
177
+ "elements" => ["records"],
178
+ "attributes" => {
179
+ "count" => { "source" => "_nsubrecs" },
180
+ },
181
+ "limit" => 1,
182
+ }
183
+ @group_by = "family_name"
184
+ @request = {
185
+ "type" => "search",
186
+ "dataset" => "Droonga",
187
+ "body" => {
188
+ "queries" => {
189
+ "families" => {
190
+ "source" => "User",
191
+ "groupBy" => @group_by,
192
+ "output" => @output,
193
+ },
194
+ },
195
+ },
196
+ }
197
+ end
198
+
199
+ def test_dependencies
200
+ reduce_inputs = ["errors", "families"]
201
+ gather_inputs = ["errors_reduced", "families_reduced"]
202
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
203
+ dependencies)
204
+ end
205
+
206
+ def test_broadcast_body
207
+ changed_output_parameters = {
208
+ "attributes" => [
209
+ { "label" => "count", "source" => "_nsubrecs" },
210
+ "_key",
211
+ ],
212
+ "unifiable" => true,
213
+ }
214
+ assert_equal({
215
+ "queries" => {
216
+ "families" => {
217
+ "source" => "User",
218
+ "groupBy" => @group_by,
219
+ "output" => @output.merge(changed_output_parameters),
220
+ },
221
+ },
222
+ },
223
+ broadcast_message["body"])
224
+ end
225
+
226
+ def test_reduce_body
227
+ assert_equal({
228
+ "families_reduced" => {
229
+ "records" => {
230
+ "type" => "sort",
231
+ "operators" => [],
232
+ "key_column" => 1,
233
+ "limit" => 1,
234
+ },
235
+ },
236
+ },
237
+ reduce_message["body"]["families"])
238
+ end
239
+
240
+ def test_gather_records
241
+ assert_equal({
242
+ "elements" => {
243
+ "records" => {
244
+ "attributes" => ["count"],
245
+ "limit" => 1,
246
+ },
247
+ },
248
+ "output" => "families",
249
+ },
250
+ gather_message["body"]["families_reduced"])
251
+ end
252
+ end
253
+
254
+ class WithComplexAttributesArrayTest < self
255
+ def setup
256
+ @output = {
257
+ "elements" => ["records"],
258
+ "attributes" => [
259
+ { "label" => "family_name", "source" => "_key" },
260
+ { "label" => "count", "source" => "_nsubrecs" },
261
+ ],
262
+ "limit" => 1,
263
+ }
264
+ @group_by = "family_name"
265
+ @request = {
266
+ "type" => "search",
267
+ "dataset" => "Droonga",
268
+ "body" => {
269
+ "queries" => {
270
+ "families" => {
271
+ "source" => "User",
272
+ "groupBy" => @group_by,
273
+ "output" => @output,
274
+ },
275
+ },
276
+ },
277
+ }
278
+ end
279
+
280
+ def test_dependencies
281
+ reduce_inputs = ["errors", "families"]
282
+ gather_inputs = ["errors_reduced", "families_reduced"]
283
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
284
+ dependencies)
285
+ end
286
+
287
+ def test_broadcast_body
288
+ changed_output_parameters = {
289
+ "unifiable" => true,
290
+ }
291
+ assert_equal({
292
+ "queries" => {
293
+ "families" => {
294
+ "source" => "User",
295
+ "groupBy" => @group_by,
296
+ "output" => @output.merge(changed_output_parameters),
297
+ },
298
+ },
299
+ },
300
+ broadcast_message["body"])
301
+ end
302
+
303
+ def test_reduce_body
304
+ assert_equal({
305
+ "families_reduced" => {
306
+ "records" => {
307
+ "type" => "sort",
308
+ "operators" => [],
309
+ "key_column" => 0,
310
+ "limit" => 1,
311
+ },
312
+ },
313
+ },
314
+ reduce_message["body"]["families"])
315
+ end
316
+
317
+ def test_gather_records
318
+ assert_equal({
319
+ "elements" => {
320
+ "records" => {
321
+ "attributes" => ["family_name", "count"],
322
+ "limit" => 1,
323
+ },
324
+ },
325
+ "output" => "families",
326
+ },
327
+ gather_message["body"]["families_reduced"])
328
+ end
329
+ end
330
+
331
+ class WithComplexAttributesArrayMissingKeyTest < self
332
+ def setup
333
+ @output = {
334
+ "elements" => ["records"],
335
+ "attributes" => [
336
+ { "label" => "count", "source" => "_nsubrecs" },
337
+ ],
338
+ "limit" => 1,
339
+ }
340
+ @group_by = "family_name"
341
+ @request = {
342
+ "type" => "search",
343
+ "dataset" => "Droonga",
344
+ "body" => {
345
+ "queries" => {
346
+ "families" => {
347
+ "source" => "User",
348
+ "groupBy" => @group_by,
349
+ "output" => @output,
350
+ },
351
+ },
352
+ },
353
+ }
354
+ end
355
+
356
+ def test_dependencies
357
+ reduce_inputs = ["errors", "families"]
358
+ gather_inputs = ["errors_reduced", "families_reduced"]
359
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
360
+ dependencies)
361
+ end
362
+
363
+ def test_broadcast_body
364
+ changed_output_parameters = {
365
+ "attributes" => [
366
+ { "label" => "count", "source" => "_nsubrecs" },
367
+ "_key",
368
+ ],
369
+ "unifiable" => true,
370
+ }
371
+ assert_equal({
372
+ "queries" => {
373
+ "families" => {
374
+ "source" => "User",
375
+ "groupBy" => @group_by,
376
+ "output" => @output.merge(changed_output_parameters),
377
+ },
378
+ },
379
+ },
380
+ broadcast_message["body"])
381
+ end
382
+
383
+ def test_reduce_body
384
+ assert_equal({
385
+ "families_reduced" => {
386
+ "records" => {
387
+ "type" => "sort",
388
+ "operators" => [],
389
+ "key_column" => 1,
390
+ "limit" => 1,
391
+ },
392
+ },
393
+ },
394
+ reduce_message["body"]["families"])
395
+ end
396
+
397
+ def test_gather_records
398
+ assert_equal({
399
+ "elements" => {
400
+ "records" => {
401
+ "attributes" => ["count"],
402
+ "limit" => 1,
403
+ },
404
+ },
405
+ "output" => "families",
406
+ },
407
+ gather_message["body"]["families_reduced"])
408
+ end
409
+ end
410
+
411
+ class SubRecodsTest < self
412
+ def setup
413
+ @output = {
414
+ "elements" => ["records"],
415
+ "attributes" => [
416
+ "_key",
417
+ "_nsubrecs",
418
+ { "label" => "users",
419
+ "source" => "_subrecs",
420
+ "attributes" => ["_key"] },
421
+ ],
422
+ "limit" => 1,
423
+ }
424
+ @group_by = {
425
+ "key" => "family_name",
426
+ "maxNSubRecords" => 3,
427
+ }
428
+ @request = {
429
+ "type" => "search",
430
+ "dataset" => "Droonga",
431
+ "body" => {
432
+ "queries" => {
433
+ "families" => {
434
+ "source" => "User",
435
+ "groupBy" => @group_by,
436
+ "output" => @output,
437
+ },
438
+ },
439
+ },
440
+ }
441
+ end
442
+
443
+ def test_dependencies
444
+ reduce_inputs = ["errors", "families"]
445
+ gather_inputs = ["errors_reduced", "families_reduced"]
446
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
447
+ dependencies)
448
+ end
449
+
450
+ def test_broadcast_body
451
+ changed_output_parameters = {
452
+ "unifiable" => true,
453
+ }
454
+ assert_equal({
455
+ "queries" => {
456
+ "families" => {
457
+ "source" => "User",
458
+ "groupBy" => @group_by,
459
+ "output" => @output.merge(changed_output_parameters),
460
+ },
461
+ },
462
+ },
463
+ broadcast_message["body"])
464
+ end
465
+
466
+ def test_reduce_body
467
+ assert_equal({
468
+ "families_reduced" => {
469
+ "records" => {
470
+ "type" => "sort",
471
+ "operators" => [],
472
+ "key_column" => 0,
473
+ "limit" => 1,
474
+ },
475
+ },
476
+ },
477
+ reduce_message["body"]["families"])
478
+ end
479
+
480
+ def test_gather_records
481
+ assert_equal({
482
+ "elements" => {
483
+ "records" => {
484
+ "attributes" => ["_key", "_nsubrecs", "users"],
485
+ "limit" => 1,
486
+ },
487
+ },
488
+ "output" => "families",
489
+ },
490
+ gather_message["body"]["families_reduced"])
491
+ end
492
+ end
493
+
494
+ class CountOnlyTest < self
495
+ def setup
496
+ @output = {
497
+ "elements" => ["count"],
498
+ }
499
+ @group_by = "family_name"
500
+ @request = {
501
+ "type" => "search",
502
+ "dataset" => "Droonga",
503
+ "body" => {
504
+ "queries" => {
505
+ "families" => {
506
+ "source" => "User",
507
+ "groupBy" => @group_by,
508
+ "output" => @output,
509
+ },
510
+ },
511
+ },
512
+ }
513
+ end
514
+
515
+ def test_dependencies
516
+ reduce_inputs = ["errors", "families"]
517
+ gather_inputs = ["errors_reduced", "families_reduced"]
518
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
519
+ dependencies)
520
+ end
521
+
522
+ def test_broadcast_body
523
+ changed_output_parameters = {
524
+ "elements" => ["count", "records"],
525
+ "attributes" => ["_key"],
526
+ "limit" => -1,
527
+ "unifiable" => true,
528
+ }
529
+ assert_equal({
530
+ "queries" => {
531
+ "families" => {
532
+ "source" => "User",
533
+ "groupBy" => @group_by,
534
+ "output" => @output.merge(changed_output_parameters),
535
+ },
536
+ },
537
+ },
538
+ broadcast_message["body"])
539
+ end
540
+
541
+ def test_reduce_body
542
+ assert_equal({
543
+ "families_reduced" => {
544
+ "count" => {
545
+ "type" => "sum",
546
+ },
547
+ "records" => {
548
+ "type" => "sort",
549
+ "operators" => [],
550
+ "key_column" => 0,
551
+ "limit" => -1,
552
+ },
553
+ },
554
+ },
555
+ reduce_message["body"]["families"])
556
+ end
557
+
558
+ def test_gather_records
559
+ assert_equal({
560
+ "elements" => {
561
+ "count" => {
562
+ "target" => "records",
563
+ },
564
+ "records" => {
565
+ "no_output" => true,
566
+ },
567
+ },
568
+ "output" => "families",
569
+ },
570
+ gather_message["body"]["families_reduced"])
571
+ end
572
+ end
573
+ end