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
|
@@ -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,21 +15,32 @@
|
|
|
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
|
+
require "droonga/plugin"
|
|
19
|
+
|
|
18
20
|
module Droonga
|
|
19
|
-
class HandlerPlugin
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
class HandlerPlugin < Plugin
|
|
22
|
+
extend PluginRegisterable
|
|
23
|
+
|
|
24
|
+
def initialize(handler)
|
|
25
|
+
super()
|
|
26
|
+
@handler = handler
|
|
27
|
+
@context = @handler.context
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def envelope
|
|
31
|
+
@handler.envelope
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def emit(value, name=nil)
|
|
35
|
+
@handler.emit(value, name)
|
|
25
36
|
end
|
|
26
37
|
|
|
27
|
-
def
|
|
28
|
-
@
|
|
38
|
+
def post(body, destination=nil)
|
|
39
|
+
@handler.post(body, destination)
|
|
29
40
|
end
|
|
30
41
|
|
|
31
|
-
def
|
|
32
|
-
|
|
42
|
+
def prefer_synchronous?(command)
|
|
43
|
+
false
|
|
33
44
|
end
|
|
34
45
|
end
|
|
35
46
|
end
|
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
module Droonga
|
|
19
|
+
class InputMessage
|
|
20
|
+
def initialize(envelope)
|
|
21
|
+
@envelope = envelope
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def adapted_envelope
|
|
25
|
+
# TODO: We can create adapted envelope non-destructively.
|
|
26
|
+
# If it is not performance issue, it is better that we don't
|
|
27
|
+
# change envelope destructively. Consider about it later.
|
|
28
|
+
@envelope
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def add_route(route)
|
|
32
|
+
@envelope["via"].push(route)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def body
|
|
36
|
+
@envelope["body"]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def body=(body)
|
|
40
|
+
@envelope["body"] = body
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def command
|
|
44
|
+
@envelope["type"]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def command=(command)
|
|
48
|
+
@envelope["type"] = command
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/droonga/job_queue.rb
CHANGED
|
@@ -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
|
|
@@ -67,6 +67,10 @@ module Droonga
|
|
|
67
67
|
MessagePack.unpack(packed_message)
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
+
def unblock
|
|
71
|
+
@queue.unblock
|
|
72
|
+
end
|
|
73
|
+
|
|
70
74
|
def close
|
|
71
75
|
@queue = nil
|
|
72
76
|
if @database
|
data/lib/droonga/logger.rb
CHANGED
|
@@ -0,0 +1,76 @@
|
|
|
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 "serverengine"
|
|
19
|
+
|
|
20
|
+
require "droonga/server"
|
|
21
|
+
require "droonga/worker"
|
|
22
|
+
require "droonga/processor"
|
|
23
|
+
|
|
24
|
+
module Droonga
|
|
25
|
+
class Partition
|
|
26
|
+
def initialize(options={})
|
|
27
|
+
@options = options
|
|
28
|
+
@n_workers = @options[:n_workers] || 0
|
|
29
|
+
@processor = Processor.new(@options)
|
|
30
|
+
@supervisor = nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def start
|
|
34
|
+
@processor.start
|
|
35
|
+
start_supervisor if @n_workers > 0
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def shutdown
|
|
39
|
+
$log.trace("partition: shutdown: start")
|
|
40
|
+
shutdown_supervisor if @supervisor
|
|
41
|
+
@processor.shutdown
|
|
42
|
+
$log.trace("partition: shutdown: done")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def process(envelope, synchronous=nil)
|
|
46
|
+
$log.trace("partition: process: start")
|
|
47
|
+
@processor.process(envelope, synchronous)
|
|
48
|
+
$log.trace("partition: process: done")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
def start_supervisor
|
|
53
|
+
@supervisor = ServerEngine::Supervisor.new(Server, Worker) do
|
|
54
|
+
force_options = {
|
|
55
|
+
:worker_type => "process",
|
|
56
|
+
:workers => @options[:n_workers],
|
|
57
|
+
:log_level => $log.level,
|
|
58
|
+
:server_process_name => "Server[#{@options[:database]}] #$0",
|
|
59
|
+
:worker_process_name => "Worker[#{@options[:database]}] #$0"
|
|
60
|
+
}
|
|
61
|
+
@options.merge(force_options)
|
|
62
|
+
end
|
|
63
|
+
@supervisor_thread = Thread.new do
|
|
64
|
+
@supervisor.main
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def shutdown_supervisor
|
|
69
|
+
$log.trace("supervisor: shutdown: start")
|
|
70
|
+
@supervisor.stop(true)
|
|
71
|
+
$log.trace("supervisor: shutdown: stopped")
|
|
72
|
+
@supervisor_thread.join
|
|
73
|
+
$log.trace("supervisor: shutdown: done")
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
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
|
+
module Droonga
|
|
19
|
+
module Pluggable
|
|
20
|
+
def shutdown
|
|
21
|
+
$log.trace("#{log_tag}: shutdown: plugin: start")
|
|
22
|
+
@plugins.each do |plugin|
|
|
23
|
+
plugin.shutdown
|
|
24
|
+
end
|
|
25
|
+
$log.trace("#{log_tag}: shutdown: plugin: done")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def processable?(command)
|
|
29
|
+
not find_plugin(command).nil?
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def process(command, *arguments)
|
|
33
|
+
plugin = find_plugin(command)
|
|
34
|
+
$log.trace("#{log_tag}: process: start: <#{command}>",
|
|
35
|
+
:plugin => plugin.class)
|
|
36
|
+
if plugin.nil?
|
|
37
|
+
raise "unknown plugin: <#{command}>: " +
|
|
38
|
+
"TODO: improve error handling"
|
|
39
|
+
end
|
|
40
|
+
plugin.process(command, *arguments)
|
|
41
|
+
$log.trace("#{log_tag}: process: done: <#{command}>",
|
|
42
|
+
:plugin => plugin.class)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
def load_plugins(names)
|
|
47
|
+
@plugins = names.collect do |name|
|
|
48
|
+
plugin = instantiate_plugin(name)
|
|
49
|
+
if plugin.nil?
|
|
50
|
+
raise "unknown plugin: <#{name}>: TODO: improve error handling"
|
|
51
|
+
end
|
|
52
|
+
plugin
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def find_plugin(command)
|
|
57
|
+
@plugins.find do |plugin|
|
|
58
|
+
plugin.processable?(command)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
data/lib/droonga/plugin.rb
CHANGED
|
@@ -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,27 +15,29 @@
|
|
|
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
|
+
require "droonga/plugin_registerable"
|
|
19
|
+
|
|
18
20
|
module Droonga
|
|
19
21
|
class Plugin
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
22
|
+
def initialize
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def start
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def shutdown
|
|
30
29
|
end
|
|
31
30
|
|
|
32
|
-
def
|
|
33
|
-
|
|
34
|
-
@name = name
|
|
31
|
+
def processable?(command)
|
|
32
|
+
self.class.processable?(command)
|
|
35
33
|
end
|
|
36
34
|
|
|
37
|
-
def
|
|
38
|
-
|
|
35
|
+
def process(command, *arguments)
|
|
36
|
+
__send__(self.class.method_name(command), *arguments)
|
|
37
|
+
rescue => exception
|
|
38
|
+
Logger.error("error while processing #{command}",
|
|
39
|
+
arguments: arguments,
|
|
40
|
+
exception: exception)
|
|
39
41
|
end
|
|
40
42
|
end
|
|
41
43
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2013
|
|
1
|
+
# Copyright (C) 2013 Droonga Project
|
|
2
2
|
#
|
|
3
3
|
# This library is free software; you can redistribute it and/or
|
|
4
4
|
# modify it under the terms of the GNU Lesser General Public
|
|
@@ -13,20 +13,20 @@
|
|
|
13
13
|
# License along with this library; if not, write to the Free Software
|
|
14
14
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
15
15
|
|
|
16
|
-
require "
|
|
17
|
-
|
|
18
|
-
require "droonga/adapter"
|
|
16
|
+
require "droonga/adapter_plugin"
|
|
19
17
|
|
|
20
18
|
module Droonga
|
|
21
|
-
class GroongaAdapter < Droonga::
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
class GroongaAdapter < Droonga::AdapterPlugin
|
|
20
|
+
repository.register("select", self)
|
|
21
|
+
|
|
24
22
|
command :select
|
|
25
|
-
def select(
|
|
23
|
+
def select(input_message)
|
|
26
24
|
command = Select.new
|
|
25
|
+
select_request = input_message.body
|
|
27
26
|
search_request = command.convert_request(select_request)
|
|
28
|
-
add_route("select_response")
|
|
29
|
-
|
|
27
|
+
input_message.add_route("select_response")
|
|
28
|
+
input_message.command = "search"
|
|
29
|
+
input_message.body = search_request
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
command :select_response
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2013
|
|
1
|
+
# Copyright (C) 2013 Droonga Project
|
|
2
2
|
#
|
|
3
3
|
# This library is free software; you can redistribute it and/or
|
|
4
4
|
# modify it under the terms of the GNU Lesser General Public
|
|
@@ -20,10 +20,12 @@ module Droonga
|
|
|
20
20
|
table = select_request["table"]
|
|
21
21
|
result_name = table + "_result"
|
|
22
22
|
match_columns = select_request["match_columns"]
|
|
23
|
-
match_to = match_columns
|
|
23
|
+
match_to = match_columns ? match_columns.split(/ *\|\| */) : []
|
|
24
24
|
query = select_request["query"]
|
|
25
|
-
output_columns = select_request["output_columns"]
|
|
25
|
+
output_columns = select_request["output_columns"] || ""
|
|
26
26
|
attributes = output_columns.split(/, */)
|
|
27
|
+
offset = (select_request["offset"] || "0").to_i
|
|
28
|
+
limit = (select_request["limit"] || "10").to_i
|
|
27
29
|
|
|
28
30
|
search_request = {
|
|
29
31
|
"queries" => {
|
|
@@ -38,6 +40,8 @@ module Droonga
|
|
|
38
40
|
"records",
|
|
39
41
|
],
|
|
40
42
|
"attributes" => attributes,
|
|
43
|
+
"offset" => offset,
|
|
44
|
+
"limit" => limit,
|
|
41
45
|
},
|
|
42
46
|
}
|
|
43
47
|
}
|
|
@@ -76,7 +80,12 @@ module Droonga
|
|
|
76
80
|
end
|
|
77
81
|
|
|
78
82
|
header = [status_code, start_time_in_unix_time, elapsed_time]
|
|
79
|
-
|
|
83
|
+
records = value["records"]
|
|
84
|
+
if records.empty?
|
|
85
|
+
results = [[count], converted_attributes]
|
|
86
|
+
else
|
|
87
|
+
results = [[count], converted_attributes, records]
|
|
88
|
+
end
|
|
80
89
|
body = [results]
|
|
81
90
|
|
|
82
91
|
[header, body]
|
|
@@ -0,0 +1,142 @@
|
|
|
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/collector_plugin"
|
|
19
|
+
|
|
20
|
+
module Droonga
|
|
21
|
+
class BasicCollector < Droonga::CollectorPlugin
|
|
22
|
+
repository.register("basic", self)
|
|
23
|
+
|
|
24
|
+
UNLIMITED = -1
|
|
25
|
+
|
|
26
|
+
command :collector_gather
|
|
27
|
+
def collector_gather(result)
|
|
28
|
+
output = body ? body[input_name] : input_name
|
|
29
|
+
if output.is_a?(Hash)
|
|
30
|
+
element = output["element"]
|
|
31
|
+
if element
|
|
32
|
+
result[element] = apply_output_range(result[element], output)
|
|
33
|
+
result[element] = apply_output_attributes_and_format(result[element], output)
|
|
34
|
+
end
|
|
35
|
+
output = output["output"]
|
|
36
|
+
end
|
|
37
|
+
emit(result, output)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def apply_output_range(items, output)
|
|
41
|
+
if items && items.is_a?(Array)
|
|
42
|
+
offset = output["offset"] || 0
|
|
43
|
+
unless offset.zero?
|
|
44
|
+
items = items[offset..-1]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
limit = output["limit"] || 0
|
|
48
|
+
unless limit == UNLIMITED
|
|
49
|
+
items = items[0...limit]
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
items
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def apply_output_attributes_and_format(items, output)
|
|
56
|
+
attributes = output["attributes"]
|
|
57
|
+
if attributes
|
|
58
|
+
format = output["format"]
|
|
59
|
+
if format == "complex"
|
|
60
|
+
items.collect! do |item|
|
|
61
|
+
complex_item = {}
|
|
62
|
+
attributes.each_with_index do |label, index|
|
|
63
|
+
complex_item[label] = item[index]
|
|
64
|
+
end
|
|
65
|
+
complex_item
|
|
66
|
+
end
|
|
67
|
+
else
|
|
68
|
+
items.collect! do |item|
|
|
69
|
+
item[0...attributes.size]
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
items
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
command :collector_reduce
|
|
77
|
+
def collector_reduce(request)
|
|
78
|
+
return unless request
|
|
79
|
+
body[input_name].each do |output, elements|
|
|
80
|
+
value = request
|
|
81
|
+
old_value = output_values[output]
|
|
82
|
+
value = reduce(elements, old_value, request) if old_value
|
|
83
|
+
emit(value, output)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def reduce(elements, *values)
|
|
88
|
+
result = {}
|
|
89
|
+
elements.each do |key, deal|
|
|
90
|
+
reduced_values = nil
|
|
91
|
+
|
|
92
|
+
case deal["type"]
|
|
93
|
+
when "sum"
|
|
94
|
+
reduced_values = values[0][key] + values[1][key]
|
|
95
|
+
when "sort"
|
|
96
|
+
reduced_values = merge(values[0][key], values[1][key], deal["operators"])
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
reduced_values = apply_output_range(reduced_values, "limit" => deal["limit"])
|
|
100
|
+
|
|
101
|
+
result[key] = reduced_values
|
|
102
|
+
end
|
|
103
|
+
return result
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def merge(x, y, operators)
|
|
107
|
+
# Normalize operators at first for optimization.
|
|
108
|
+
operators ||= []
|
|
109
|
+
operators = operators.collect do |operator|
|
|
110
|
+
if operator.is_a?(String)
|
|
111
|
+
{ "operator" => operator }
|
|
112
|
+
else
|
|
113
|
+
operator
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
index = 0
|
|
118
|
+
y.each do |_y|
|
|
119
|
+
loop do
|
|
120
|
+
_x = x[index]
|
|
121
|
+
break unless _x
|
|
122
|
+
break if compare(_y, _x, operators)
|
|
123
|
+
index += 1
|
|
124
|
+
end
|
|
125
|
+
x.insert(index, _y)
|
|
126
|
+
index += 1
|
|
127
|
+
end
|
|
128
|
+
return x
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def compare(x, y, operators)
|
|
132
|
+
operators.each_with_index do |operator, index|
|
|
133
|
+
column = operator["column"] || index
|
|
134
|
+
operator = operator["operator"]
|
|
135
|
+
_x = x[column]
|
|
136
|
+
_y = y[column]
|
|
137
|
+
return true if _x.__send__(operator, _y)
|
|
138
|
+
end
|
|
139
|
+
return false
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|