fluent-plugin-droonga 0.0.2 → 0.7.0
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/.gitignore +6 -0
- data/.yardopts +7 -0
- data/Gemfile +14 -2
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/Rakefile +27 -5
- data/benchmark/benchmark.rb +1 -1
- data/benchmark/utils.rb +9 -6
- data/benchmark/watch/benchmark-notify.rb +2 -2
- data/benchmark/watch/benchmark-publish.rb +1 -1
- data/benchmark/watch/benchmark-scan.rb +1 -1
- data/benchmark/watch/catalog.json +1 -1
- data/bin/grn2jsons +1 -1
- data/fluent-plugin-droonga.gemspec +5 -3
- data/lib/droonga/adapter.rb +13 -130
- data/lib/droonga/adapter_plugin.rb +51 -0
- data/lib/droonga/catalog.rb +2 -2
- data/lib/droonga/collector.rb +107 -0
- data/lib/droonga/collector_plugin.rb +82 -0
- data/lib/droonga/command_mapper.rb +1 -1
- data/lib/droonga/{proxy.rb → dispatcher.rb} +116 -151
- data/lib/droonga/distributor.rb +51 -0
- data/lib/droonga/distributor_plugin.rb +59 -0
- data/lib/droonga/engine.rb +9 -50
- data/lib/droonga/farm.rb +47 -0
- data/lib/droonga/forwarder.rb +125 -0
- data/lib/droonga/handler.rb +69 -60
- data/lib/droonga/handler_plugin.rb +22 -11
- data/lib/droonga/input_message.rb +51 -0
- data/lib/droonga/job_queue.rb +5 -1
- data/lib/droonga/job_queue_schema.rb +1 -1
- data/lib/droonga/logger.rb +1 -1
- data/lib/droonga/partition.rb +76 -0
- data/lib/droonga/pluggable.rb +62 -0
- data/lib/droonga/plugin.rb +18 -16
- data/lib/droonga/plugin/{adapter_groonga.rb → adapter/groonga.rb} +10 -10
- data/lib/droonga/plugin/adapter/groonga/select.rb +13 -4
- data/lib/droonga/plugin/collector/basic.rb +142 -0
- data/lib/droonga/plugin/distributor/crud.rb +43 -0
- data/lib/droonga/plugin/distributor/groonga.rb +37 -0
- data/lib/droonga/plugin/distributor/search.rb +273 -0
- data/lib/droonga/plugin/distributor/watch.rb +39 -0
- data/lib/droonga/plugin/{handler_add.rb → handler/add.rb} +6 -6
- data/lib/droonga/plugin/{handler_forward.rb → handler/forward.rb} +9 -4
- data/lib/droonga/plugin/{handler_groonga.rb → handler/groonga.rb} +36 -4
- data/lib/droonga/plugin/handler/groonga/column_create.rb +5 -9
- data/lib/droonga/plugin/handler/groonga/table_create.rb +9 -18
- data/lib/droonga/plugin/{handler_search.rb → handler/search.rb} +4 -4
- data/lib/droonga/plugin/{handler_watch.rb → handler/watch.rb} +4 -4
- data/lib/droonga/plugin_loader.rb +45 -0
- data/lib/droonga/plugin_registerable.rb +51 -0
- data/lib/droonga/plugin_repository.rb +56 -0
- data/lib/droonga/processor.rb +64 -0
- data/lib/droonga/searcher.rb +16 -7
- data/lib/droonga/server.rb +5 -9
- data/lib/droonga/sweeper.rb +1 -1
- data/lib/droonga/watch_schema.rb +1 -1
- data/lib/droonga/watcher.rb +1 -1
- data/lib/droonga/worker.rb +21 -9
- data/lib/fluent/plugin/out_droonga.rb +33 -15
- data/lib/groonga_command_converter.rb +1 -1
- data/sample/cluster/fluentd.conf +0 -1
- data/test/command/config/default/catalog.json +43 -0
- data/test/command/config/default/fluentd.conf +11 -0
- data/test/command/fixture/documents.jsons +208 -0
- data/test/command/fixture/user-table-array.jsons +38 -0
- data/test/command/fixture/user-table.jsons +38 -0
- data/test/command/run-test.rb +35 -0
- data/test/command/suite/add/minimum.expected +12 -0
- data/test/command/suite/add/minimum.test +11 -0
- data/test/command/suite/add/with-values.expected +12 -0
- data/test/command/suite/add/with-values.test +17 -0
- data/test/command/suite/add/without-key.expected +12 -0
- data/test/command/suite/add/without-key.test +16 -0
- data/test/command/suite/groonga/column_create/scalar.expected +34 -0
- data/test/command/suite/groonga/column_create/scalar.test +17 -0
- data/test/command/suite/groonga/column_create/vector.expected +34 -0
- data/test/command/suite/groonga/column_create/vector.test +18 -0
- data/test/command/suite/groonga/select/minimum.expected +26 -0
- data/test/command/suite/groonga/select/minimum.test +8 -0
- data/test/command/suite/groonga/table_create/array.expected +17 -0
- data/test/command/suite/groonga/table_create/array.test +8 -0
- data/test/command/suite/groonga/table_create/hash.expected +17 -0
- data/test/command/suite/groonga/table_create/hash.test +8 -0
- data/test/command/suite/search/array-attribute-label.expected +25 -0
- data/test/command/suite/search/array-attribute-label.test +30 -0
- data/test/command/suite/search/chained-queries.expected +45 -0
- data/test/command/suite/search/chained-queries.test +43 -0
- data/test/command/suite/search/complex.expected +52 -0
- data/test/command/suite/search/complex.test +25 -0
- data/test/command/suite/search/condition-nested.expected +19 -0
- data/test/command/suite/search/condition-nested.test +29 -0
- data/test/command/suite/search/condition-query.expected +28 -0
- data/test/command/suite/search/condition-query.test +25 -0
- data/test/command/suite/search/condition-script.expected +28 -0
- data/test/command/suite/search/condition-script.test +28 -0
- data/test/command/suite/search/hash-attribute-label.expected +34 -0
- data/test/command/suite/search/hash-attribute-label.test +38 -0
- data/test/command/suite/search/minimum.expected +13 -0
- data/test/command/suite/search/minimum.test +16 -0
- data/test/command/suite/search/multiple-queries.expected +39 -0
- data/test/command/suite/search/multiple-queries.test +39 -0
- data/test/command/suite/search/output-range.expected +28 -0
- data/test/command/suite/search/output-range.test +25 -0
- data/test/command/suite/search/simple.expected +52 -0
- data/test/command/suite/search/simple.test +24 -0
- data/test/command/suite/search/sort-and-output-range.expected +25 -0
- data/test/command/suite/search/sort-and-output-range.test +29 -0
- data/test/command/suite/search/sort-range.expected +28 -0
- data/test/command/suite/search/sort-range.test +28 -0
- data/test/command/suite/search/sort-with-invisible-column.expected +28 -0
- data/test/command/suite/search/sort-with-invisible-column.test +28 -0
- data/test/unit/fixtures/array.grn +18 -0
- data/test/{fixtures → unit/fixtures}/catalog.json +0 -0
- data/test/{fixtures → unit/fixtures}/document.grn +20 -9
- data/test/unit/fixtures/reference/array.grn +11 -0
- data/test/unit/fixtures/reference/hash.grn +7 -0
- data/test/{helper.rb → unit/helper.rb} +2 -1
- data/test/{helper → unit/helper}/fixture.rb +1 -1
- data/test/unit/helper/plugin_helper.rb +38 -0
- data/test/{helper → unit/helper}/sandbox.rb +19 -6
- data/test/{helper → unit/helper}/stub_worker.rb +1 -1
- data/test/{helper → unit/helper}/watch_helper.rb +1 -13
- data/test/{plugin → unit/plugin}/adapter/groonga/test_select.rb +108 -4
- data/test/unit/plugin/collector/test_basic.rb +558 -0
- data/test/unit/plugin/distributor/test_search.rb +914 -0
- data/test/{plugin → unit/plugin}/handler/groonga/test_column_create.rb +18 -14
- data/test/{plugin → unit/plugin}/handler/groonga/test_table_create.rb +13 -11
- data/test/{plugin/handler/test_handler_add.rb → unit/plugin/handler/test_add.rb} +2 -14
- data/test/{plugin/handler/test_handler_groonga.rb → unit/plugin/handler/test_groonga.rb} +6 -26
- data/test/unit/plugin/handler/test_search.rb +601 -0
- data/test/{plugin/handler/test_handler_watch.rb → unit/plugin/handler/test_watch.rb} +2 -2
- data/test/{run-test.rb → unit/run-test.rb} +3 -3
- data/test/{test_adapter.rb → unit/test_adapter.rb} +17 -14
- data/test/{test_catalog.rb → unit/test_catalog.rb} +4 -4
- data/test/{test_command_mapper.rb → unit/test_command_mapper.rb} +1 -1
- data/test/{test_groonga_command_converter.rb → unit/test_groonga_command_converter.rb} +3 -3
- data/test/{test_job_queue_schema.rb → unit/test_job_queue_schema.rb} +1 -1
- data/test/{test_output.rb → unit/test_output.rb} +9 -9
- data/test/{test_handler.rb → unit/test_plugin.rb} +19 -22
- data/test/unit/test_plugin_repository.rb +89 -0
- data/test/{test_sweeper.rb → unit/test_sweeper.rb} +1 -1
- data/test/{test_watch_schema.rb → unit/test_watch_schema.rb} +1 -1
- data/test/{test_watcher.rb → unit/test_watcher.rb} +1 -1
- metadata +226 -66
- data/lib/droonga/executor.rb +0 -289
- data/lib/droonga/plugin/handler_proxy.rb +0 -82
- data/test/plugin/handler/test_handler_search.rb +0 -512
- data/test/test_worker.rb +0 -144
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
|
4
|
+
#
|
|
5
|
+
# This library is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
# License version 2.1 as published by the Free Software Foundation.
|
|
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
17
|
+
|
|
18
|
+
require "droonga/distributor_plugin"
|
|
19
|
+
|
|
20
|
+
module Droonga
|
|
21
|
+
class CRUDDistributor < Droonga::DistributorPlugin
|
|
22
|
+
repository.register("crud", self)
|
|
23
|
+
|
|
24
|
+
command :add
|
|
25
|
+
def add(envelope)
|
|
26
|
+
key = envelope["body"]["key"] || rand.to_s
|
|
27
|
+
scatter_all(envelope, key)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
command :update
|
|
31
|
+
def update(envelope)
|
|
32
|
+
key = envelope["body"]["key"] || rand.to_s
|
|
33
|
+
scatter_all(envelope, key)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# TODO: What is this?
|
|
37
|
+
command :reset
|
|
38
|
+
def reset(envelope)
|
|
39
|
+
key = envelope["body"]["key"] || rand.to_s
|
|
40
|
+
scatter_all(envelope, key)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
|
4
|
+
#
|
|
5
|
+
# This library is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
# License version 2.1 as published by the Free Software Foundation.
|
|
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
17
|
+
|
|
18
|
+
require "droonga/distributor_plugin"
|
|
19
|
+
|
|
20
|
+
module Droonga
|
|
21
|
+
class GroongaDistributor < Droonga::DistributorPlugin
|
|
22
|
+
repository.register("groonga", self)
|
|
23
|
+
|
|
24
|
+
command :table_create
|
|
25
|
+
def table_create(envelope)
|
|
26
|
+
unless envelope["dataset"]
|
|
27
|
+
raise "dataset must be set. FIXME: This error should return client."
|
|
28
|
+
end
|
|
29
|
+
broadcast_all(envelope)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
command :column_create
|
|
33
|
+
def column_create(envelope)
|
|
34
|
+
broadcast_all(envelope)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
|
4
|
+
#
|
|
5
|
+
# This library is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
# License version 2.1 as published by the Free Software Foundation.
|
|
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
17
|
+
|
|
18
|
+
require "droonga/distributor_plugin"
|
|
19
|
+
|
|
20
|
+
module Droonga
|
|
21
|
+
class SearchDistributor < Droonga::DistributorPlugin
|
|
22
|
+
repository.register("search", self)
|
|
23
|
+
|
|
24
|
+
command :search
|
|
25
|
+
def search(envelope)
|
|
26
|
+
message = []
|
|
27
|
+
input_names = []
|
|
28
|
+
output_names = []
|
|
29
|
+
output_mapper = {}
|
|
30
|
+
|
|
31
|
+
request = envelope["body"]
|
|
32
|
+
request["queries"].each do |input_name, query|
|
|
33
|
+
output = query["output"]
|
|
34
|
+
# Skip reducing phase for a result with no output.
|
|
35
|
+
next unless output
|
|
36
|
+
|
|
37
|
+
input_names << input_name
|
|
38
|
+
output_name = input_name + "_reduced"
|
|
39
|
+
output_names << output_name
|
|
40
|
+
output_mapper[output_name] = {
|
|
41
|
+
"output" => input_name,
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# The collector module supports only "simple" format search results.
|
|
45
|
+
# So we have to override the format and restore it on the gathering
|
|
46
|
+
# phase.
|
|
47
|
+
final_format = output["format"] || "simple"
|
|
48
|
+
output["format"] = "simple"
|
|
49
|
+
|
|
50
|
+
final_offset, final_limit = calculate_offset_and_limit!(query)
|
|
51
|
+
|
|
52
|
+
elements = {}
|
|
53
|
+
output["elements"].each do |element|
|
|
54
|
+
case element
|
|
55
|
+
when "count"
|
|
56
|
+
elements[element] = {
|
|
57
|
+
"type" => "sum",
|
|
58
|
+
}
|
|
59
|
+
when "records"
|
|
60
|
+
# Skip reducing phase for a result with no record output.
|
|
61
|
+
next if final_limit.zero?
|
|
62
|
+
|
|
63
|
+
# Append sort key attributes to the list of output attributes
|
|
64
|
+
# temporarily, for the reducing phase. After all extra columns
|
|
65
|
+
# are removed on the gathering phase.
|
|
66
|
+
final_attributes = collect_output_attributes(output["attributes"])
|
|
67
|
+
output["attributes"] = format_attributes_to_array_style(output["attributes"])
|
|
68
|
+
output["attributes"] += collect_sort_attributes(output["attributes"], query["sortBy"])
|
|
69
|
+
|
|
70
|
+
elements[element] = sort_reducer(output["attributes"], query["sortBy"])
|
|
71
|
+
# On the reducing phase, we apply only "limit". We cannot apply
|
|
72
|
+
# "offset" on this phase because the collecter merges a pair of
|
|
73
|
+
# results step by step even if there are three or more results.
|
|
74
|
+
# Instead, we apply "offset" on the gethering phase.
|
|
75
|
+
elements[element]["limit"] = output["limit"]
|
|
76
|
+
|
|
77
|
+
output_mapper[output_name]["element"] = element
|
|
78
|
+
output_mapper[output_name]["offset"] = final_offset
|
|
79
|
+
output_mapper[output_name]["limit"] = final_limit
|
|
80
|
+
output_mapper[output_name]["format"] = final_format
|
|
81
|
+
output_mapper[output_name]["attributes"] = final_attributes
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
reducer = {
|
|
86
|
+
"type" => "reduce",
|
|
87
|
+
"body" => {
|
|
88
|
+
input_name => {
|
|
89
|
+
output_name => elements,
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
"inputs" => [input_name], # XXX should be placed in the "body"?
|
|
93
|
+
"outputs" => [output_name], # XXX should be placed in the "body"?
|
|
94
|
+
}
|
|
95
|
+
message << reducer
|
|
96
|
+
end
|
|
97
|
+
gatherer = {
|
|
98
|
+
"type" => "gather",
|
|
99
|
+
"body" => output_mapper,
|
|
100
|
+
"inputs" => output_names, # XXX should be placed in the "body"?
|
|
101
|
+
"post" => true, # XXX should be placed in the "body"?
|
|
102
|
+
}
|
|
103
|
+
message << gatherer
|
|
104
|
+
searcher = {
|
|
105
|
+
"type" => "broadcast",
|
|
106
|
+
"command" => "search", # XXX should be placed in the "body"?
|
|
107
|
+
"dataset" => envelope["dataset"] || request["dataset"],
|
|
108
|
+
"body" => request,
|
|
109
|
+
"outputs" => input_names, # XXX should be placed in the "body"?
|
|
110
|
+
"replica" => "random", # XXX should be placed in the "body"?
|
|
111
|
+
}
|
|
112
|
+
message.push(searcher)
|
|
113
|
+
post(message)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
private
|
|
117
|
+
UNLIMITED = -1
|
|
118
|
+
|
|
119
|
+
def calculate_offset_and_limit!(query)
|
|
120
|
+
rich_sort = query["sortBy"].is_a?(Hash)
|
|
121
|
+
|
|
122
|
+
have_records = false
|
|
123
|
+
if query["output"] &&
|
|
124
|
+
query["output"]["elements"].is_a?(Array) &&
|
|
125
|
+
query["output"]["elements"].include?("records")
|
|
126
|
+
have_records = true
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Offset for workers must be zero, because we have to apply "limit" and
|
|
130
|
+
# "offset" on the last gapthering phase instaed of each reducing phase.
|
|
131
|
+
sort_offset = 0
|
|
132
|
+
if rich_sort
|
|
133
|
+
sort_offset = query["sortBy"]["offset"] || 0
|
|
134
|
+
query["sortBy"]["offset"] = 0
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
output_offset = query["output"]["offset"] || 0
|
|
138
|
+
query["output"]["offset"] = 0 if have_records
|
|
139
|
+
|
|
140
|
+
final_offset = sort_offset + output_offset
|
|
141
|
+
|
|
142
|
+
# We have to calculate limit based on offset.
|
|
143
|
+
# <A, B = limited integer (0...MAXINT)>
|
|
144
|
+
# | sort limit | output limit | => | worker's sort limit | worker's output limit | final limit |
|
|
145
|
+
# ============================= ====================================================================
|
|
146
|
+
# | UNLIMITED | UNLIMITED | => | UNLIMITED | UNLIMITED | UNLIMITED |
|
|
147
|
+
# | UNLIMITED | B | => | final_offset + B | final_offset + B | B |
|
|
148
|
+
# | A | UNLIMITED | => | final_offset + A | final_offset + A | A |
|
|
149
|
+
# | A | B | => | final_offset + min(A, B) | final_offset + min(A, B)| min(A, B) |
|
|
150
|
+
sort_limit = UNLIMITED
|
|
151
|
+
if rich_sort
|
|
152
|
+
sort_limit = query["sortBy"]["limit"] || UNLIMITED
|
|
153
|
+
end
|
|
154
|
+
output_limit = query["output"]["limit"] || 0
|
|
155
|
+
|
|
156
|
+
final_limit = 0
|
|
157
|
+
if sort_limit == UNLIMITED && output_limit == UNLIMITED
|
|
158
|
+
final_limit = UNLIMITED
|
|
159
|
+
query["output"]["limit"] = UNLIMITED
|
|
160
|
+
else
|
|
161
|
+
if sort_limit == UNLIMITED
|
|
162
|
+
final_limit = output_limit
|
|
163
|
+
elsif output_limit == UNLIMITED
|
|
164
|
+
final_limit = sort_limit
|
|
165
|
+
else
|
|
166
|
+
final_limit = [sort_limit, output_limit].min
|
|
167
|
+
end
|
|
168
|
+
query["sortBy"]["limit"] = final_offset + final_limit if rich_sort
|
|
169
|
+
query["output"]["limit"] = final_offset + final_limit
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
[final_offset, final_limit]
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def format_attributes_to_array_style(attributes)
|
|
176
|
+
attributes ||= []
|
|
177
|
+
if attributes.is_a?(Hash)
|
|
178
|
+
attributes.keys.collect do |key|
|
|
179
|
+
attribute = attributes[key]
|
|
180
|
+
case attribute
|
|
181
|
+
when String
|
|
182
|
+
{
|
|
183
|
+
"label" => key,
|
|
184
|
+
"source" => attribute,
|
|
185
|
+
}
|
|
186
|
+
when Hash
|
|
187
|
+
attribute["label"] = key
|
|
188
|
+
attribute
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
else
|
|
192
|
+
attributes
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def collect_output_attributes(attributes)
|
|
197
|
+
attributes ||= []
|
|
198
|
+
if attributes.is_a?(Hash)
|
|
199
|
+
attributes.keys
|
|
200
|
+
else
|
|
201
|
+
attributes.collect do |attribute|
|
|
202
|
+
if attribute.is_a?(Hash)
|
|
203
|
+
attribute["label"] || attribute["source"]
|
|
204
|
+
else
|
|
205
|
+
attribute
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def collect_source_column_names(attributes)
|
|
212
|
+
attributes ||= []
|
|
213
|
+
if attributes.is_a?(Hash)
|
|
214
|
+
attributes_hash = attributes
|
|
215
|
+
attributes = []
|
|
216
|
+
attributes_hash.each do |key, attribute|
|
|
217
|
+
attributes << attribute["source"] || key
|
|
218
|
+
end
|
|
219
|
+
attributes
|
|
220
|
+
else
|
|
221
|
+
attributes.collect do |attribute|
|
|
222
|
+
if attribute.is_a?(Hash)
|
|
223
|
+
attribute["source"] || attribute["label"]
|
|
224
|
+
else
|
|
225
|
+
attribute
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def collect_sort_attributes(attributes, sort_keys)
|
|
232
|
+
sort_keys ||= []
|
|
233
|
+
sort_keys = sort_keys["keys"] || [] if sort_keys.is_a?(Hash)
|
|
234
|
+
|
|
235
|
+
attributes = collect_source_column_names(attributes)
|
|
236
|
+
|
|
237
|
+
sort_attributes = sort_keys.collect do |key|
|
|
238
|
+
key = key[1..-1] if key[0] == "-"
|
|
239
|
+
key
|
|
240
|
+
end
|
|
241
|
+
sort_attributes.reject! do |attribute|
|
|
242
|
+
attributes.include?(attribute)
|
|
243
|
+
end
|
|
244
|
+
sort_attributes
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
ASCENDING_OPERATOR = "<".freeze
|
|
248
|
+
DESCENDING_OPERATOR = ">".freeze
|
|
249
|
+
|
|
250
|
+
def sort_reducer(attributes, sort_keys)
|
|
251
|
+
attributes ||= []
|
|
252
|
+
sort_keys ||= []
|
|
253
|
+
sort_keys = sort_keys["keys"] || [] if sort_keys.is_a?(Hash)
|
|
254
|
+
|
|
255
|
+
operators = sort_keys.collect do |sort_key|
|
|
256
|
+
operator = ASCENDING_OPERATOR
|
|
257
|
+
if sort_key[0] == "-"
|
|
258
|
+
operator = DESCENDING_OPERATOR
|
|
259
|
+
sort_key = sort_key[1..-1]
|
|
260
|
+
end
|
|
261
|
+
{
|
|
262
|
+
"operator" => operator,
|
|
263
|
+
"column" => attributes.index(sort_key),
|
|
264
|
+
}
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
{
|
|
268
|
+
"type" => "sort",
|
|
269
|
+
"operators" => operators,
|
|
270
|
+
}
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
|
4
|
+
#
|
|
5
|
+
# This library is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
# License version 2.1 as published by the Free Software Foundation.
|
|
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
17
|
+
|
|
18
|
+
require "droonga/distributor_plugin"
|
|
19
|
+
|
|
20
|
+
module Droonga
|
|
21
|
+
class WatchDistributor < Droonga::DistributorPlugin
|
|
22
|
+
repository.register("watch", self)
|
|
23
|
+
|
|
24
|
+
command "watch.feed" => :feed
|
|
25
|
+
def feed(envelope)
|
|
26
|
+
broadcast_all(envelope)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
command "watch.subscribe" => :subscribe
|
|
30
|
+
def subscribe(envelope)
|
|
31
|
+
broadcast_all(envelope)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
command "watch.unsubscribe" => :unsubscribe
|
|
35
|
+
def unsubscribe(envelope)
|
|
36
|
+
broadcast_all(envelope)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2013
|
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
|
4
4
|
#
|
|
5
5
|
# This library is free software; you can redistribute it and/or
|
|
6
6
|
# modify it under the terms of the GNU Lesser General Public
|
|
@@ -17,20 +17,20 @@
|
|
|
17
17
|
|
|
18
18
|
require "groonga"
|
|
19
19
|
|
|
20
|
-
require "droonga/
|
|
20
|
+
require "droonga/handler_plugin"
|
|
21
21
|
|
|
22
22
|
module Droonga
|
|
23
|
-
class AddHandler < Droonga::
|
|
24
|
-
|
|
23
|
+
class AddHandler < Droonga::HandlerPlugin
|
|
24
|
+
repository.register("add", self)
|
|
25
25
|
|
|
26
26
|
command :add
|
|
27
27
|
def add(request)
|
|
28
|
-
outputs =
|
|
28
|
+
outputs = process_add(request)
|
|
29
29
|
emit(outputs)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
private
|
|
33
|
-
def
|
|
33
|
+
def process_add(request)
|
|
34
34
|
table = @context[request["table"]]
|
|
35
35
|
return [false] unless table
|
|
36
36
|
if table.support_key?
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2013
|
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
|
4
4
|
#
|
|
5
5
|
# This library is free software; you can redistribute it and/or
|
|
6
6
|
# modify it under the terms of the GNU Lesser General Public
|
|
@@ -15,12 +15,16 @@
|
|
|
15
15
|
# License along with this library; if not, write to the Free Software
|
|
16
16
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
=begin
|
|
19
|
+
|
|
20
|
+
TODO: What is this?
|
|
21
|
+
|
|
22
|
+
require "droonga/legacy_plugin"
|
|
19
23
|
require "droonga/logger"
|
|
20
24
|
|
|
21
25
|
module Droonga
|
|
22
|
-
class MergeHandler < Droonga::
|
|
23
|
-
Droonga::
|
|
26
|
+
class MergeHandler < Droonga::LegacyPlugin
|
|
27
|
+
Droonga::LegacyPlugin.repository.register("forward", self)
|
|
24
28
|
|
|
25
29
|
CONFIG_FILE_PATH = 'config.json'
|
|
26
30
|
|
|
@@ -68,3 +72,4 @@ module Droonga
|
|
|
68
72
|
end
|
|
69
73
|
end
|
|
70
74
|
end
|
|
75
|
+
=end
|