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
@@ -15,30 +15,39 @@
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/distributor_plugin"
18
+ require "droonga/planner_plugin"
19
19
 
20
20
  module Droonga
21
- class WatchDistributor < Droonga::DistributorPlugin
21
+ class WatchPlanner < Droonga::PlannerPlugin
22
22
  repository.register("watch", self)
23
23
 
24
24
  command "watch.feed" => :feed
25
25
  def feed(message)
26
- broadcast_all(message)
26
+ broadcast(message)
27
27
  end
28
28
 
29
29
  command "watch.subscribe" => :subscribe
30
30
  def subscribe(message)
31
- broadcast_all(message)
31
+ broadcast(message)
32
32
  end
33
33
 
34
34
  command "watch.unsubscribe" => :unsubscribe
35
35
  def unsubscribe(message)
36
- broadcast_all(message)
36
+ broadcast(message)
37
37
  end
38
38
 
39
39
  command "watch.sweep" => :sweep
40
40
  def sweep(message)
41
- broadcast_all(message)
41
+ broadcast(message)
42
+ end
43
+
44
+ private
45
+ def broadcast(message)
46
+ super(message,
47
+ :write => true,
48
+ :reduce => {
49
+ "success" => "and"
50
+ })
42
51
  end
43
52
  end
44
53
  end
@@ -15,6 +15,8 @@
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 "pathname"
19
+
18
20
  module Droonga
19
21
  class PluginLoader
20
22
  class << self
@@ -29,6 +31,13 @@ module Droonga
29
31
  loader.load
30
32
  end
31
33
  end
34
+
35
+ Pathname.glob("#{load_path}/droonga/plugins/*.rb") do |plugin_path|
36
+ relative_plugin_path =
37
+ plugin_path.relative_path_from(Pathname(load_path))
38
+ require_path = relative_plugin_path.to_s.gsub(/\.rb\z/, "")
39
+ require require_path
40
+ end
32
41
  end
33
42
  end
34
43
  end
@@ -39,6 +48,7 @@ module Droonga
39
48
  end
40
49
 
41
50
  def load
51
+ return if @type == "metadata"
42
52
  require "droonga/plugin/#{@type}/#{@name}"
43
53
  end
44
54
  end
@@ -15,15 +15,17 @@
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/command_mapper"
19
- require "droonga/plugin_repository"
18
+ require "droonga/command"
19
+ require "droonga/command_repository"
20
+ require "droonga/legacy_plugin_repository"
20
21
 
21
22
  module Droonga
22
23
  module PluginRegisterable
23
24
  class << self
24
25
  def extended(plugin_class)
25
26
  super
26
- plugin_class.class_variable_set(:@@repository, PluginRepository.new)
27
+ plugin_class.class_variable_set(:@@repository,
28
+ LegacyPluginRepository.new)
27
29
  end
28
30
  end
29
31
 
@@ -33,19 +35,41 @@ module Droonga
33
35
 
34
36
  def inherited(sub_class)
35
37
  super
36
- sub_class.instance_variable_set(:@command_mapper, CommandMapper.new)
38
+ sub_class.instance_variable_set(:@command_repository,
39
+ CommandRepository.new)
37
40
  end
38
41
 
39
- def command(name_or_map)
40
- @command_mapper.register(name_or_map)
42
+ def command(method_name_or_map, options={})
43
+ if method_name_or_map.is_a?(Hash)
44
+ type, method_name = method_name_or_map.to_a.first
45
+ options[:pattern] ||= ["type", :equal, type.to_s]
46
+ else
47
+ method_name = method_name_or_map
48
+ options[:pattern] ||= ["type", :equal, method_name.to_s]
49
+ end
50
+ command = Command.new(method_name, options)
51
+ @command_repository.register(command)
52
+ end
53
+
54
+ def commands
55
+ @command_repository.commands
56
+ end
57
+
58
+ def find_command(message)
59
+ @command_repository.find(message)
41
60
  end
42
61
 
43
- def method_name(command)
44
- @command_mapper[command]
62
+ def method_name(message)
63
+ message = {"type" => message.to_s} unless message.is_a?(Hash)
64
+ command = find_command(message)
65
+ return nil if command.nil?
66
+ command.method_name
45
67
  end
46
68
 
47
- def processable?(command)
48
- not method_name(command).nil?
69
+ def processable?(message)
70
+ message = {"type" => message.to_s} unless message.is_a?(Hash)
71
+ command = find_command(message)
72
+ not command.nil?
49
73
  end
50
74
  end
51
75
  end
@@ -0,0 +1,58 @@
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
+ module Droonga
17
+ class PluginRegistry
18
+ include Enumerable
19
+
20
+ def initialize
21
+ @plugins = {}
22
+ end
23
+
24
+ def each(&block)
25
+ @plugins.each(&block)
26
+ end
27
+
28
+ def register(name, plugin_module)
29
+ @plugins[name] = plugin_module
30
+ end
31
+
32
+ def [](name)
33
+ @plugins[name]
34
+ end
35
+
36
+ def clear
37
+ @plugins.clear
38
+ end
39
+
40
+ def find_sub_classes(name, klass)
41
+ plugin_module = self[name]
42
+ return [] if plugin_module.nil?
43
+ sub_classes = []
44
+ collect_sub_classes_recursive(plugin_module, klass, sub_classes)
45
+ sub_classes
46
+ end
47
+
48
+ private
49
+ def collect_sub_classes_recursive(base, klass, sub_classes)
50
+ base.constants.each do |constant_name|
51
+ constant = base.const_get(constant_name)
52
+ next unless constant.is_a?(Module)
53
+ sub_classes << constant if constant < klass
54
+ collect_sub_classes_recursive(constant, klass, sub_classes)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,124 @@
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
+ require "groonga"
17
+
18
+ require "droonga/plugin"
19
+ require "droonga/message_processing_error"
20
+
21
+ module Droonga
22
+ module Plugins
23
+ module CRUD
24
+ Plugin.registry.register("crud", self)
25
+
26
+ class Adapter < Droonga::Adapter
27
+ message.input_pattern = ["type", :equal, "add"]
28
+ message.output_pattern = ["body.success", :exist?]
29
+
30
+ def adapt_output(output_message)
31
+ success = output_message.body["success"]
32
+ unless success.nil?
33
+ output_message.body = output_message.body["success"]
34
+ end
35
+ end
36
+ end
37
+
38
+ class Handler < Droonga::Handler
39
+ message.type = "add"
40
+
41
+ class MissingTableParameter < BadRequest
42
+ def initialize
43
+ super("\"table\" must be specified.")
44
+ end
45
+ end
46
+
47
+ class MissingPrimaryKeyParameter < BadRequest
48
+ def initialize(table_name)
49
+ super("\"key\" must be specified. " +
50
+ "The table #{table_name.inspect} requires a primary key for a new record.")
51
+ end
52
+ end
53
+
54
+ class UnknownTable < NotFound
55
+ def initialize(table_name)
56
+ super("The table #{table_name.inspect} does not exist in the dataset.")
57
+ end
58
+ end
59
+
60
+ class InvalidValue < BadRequest
61
+ def initialize(column, value, request)
62
+ super("The column #{column.inspect} cannot store the value #{value.inspect}.",
63
+ request)
64
+ end
65
+ end
66
+
67
+ class UnknownColumn < NotFound
68
+ def initialize(column, table, request)
69
+ super("The column #{column.inspect} does not exist in the table #{table.inspect}.",
70
+ request)
71
+ end
72
+ end
73
+
74
+ def handle(message, messenger)
75
+ succeeded = process_add(message.request)
76
+ outputs = {
77
+ "success" => succeeded,
78
+ }
79
+ messenger.emit(outputs)
80
+ end
81
+
82
+ private
83
+ def process_add(request)
84
+ raise MissingTableParameter.new unless request.include?("table")
85
+
86
+ table = @context[request["table"]]
87
+ raise UnknownTable.new(request["table"]) unless table
88
+
89
+ if table.support_key?
90
+ unless request.include?("key")
91
+ raise MissingPrimaryKeyParameter.new(request["table"])
92
+ end
93
+ end
94
+
95
+ add_record(table, request)
96
+ true
97
+ end
98
+
99
+ def add_record(table, request)
100
+ record = nil
101
+ if table.support_key?
102
+ record = table.add(request["key"])
103
+ else
104
+ record = table.add
105
+ end
106
+ (request["values"] || []).each do |column, value|
107
+ begin
108
+ record[column] = value
109
+ rescue ::Groonga::InvalidArgument => error
110
+ record.delete if record.added?
111
+ raise InvalidValue.new(column, value, request)
112
+ rescue ArgumentError => error
113
+ record.delete if record.added?
114
+ raise InvalidValue.new(column, value, request)
115
+ rescue ::Groonga::NoSuchColumn => error
116
+ record.delete if record.added?
117
+ raise UnknownColumn.new(column, request["table"], request)
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,50 @@
1
+ # Copyright (C) 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
+ require "droonga/plugin"
17
+
18
+ module Droonga
19
+ module Plugins
20
+ module Error
21
+ Plugin.registry.register("error", self)
22
+
23
+ class Adapter < Droonga::Adapter
24
+ message.output_pattern = ["body.errors", :exist?]
25
+
26
+ def adapt_output(output_message)
27
+ errors = output_message.body["errors"]
28
+ if errors && !errors.empty?
29
+ output_message.errors = errors
30
+
31
+ status_codes = []
32
+ errors.values.each do |error|
33
+ status_codes << error["statusCode"]
34
+ end
35
+ status_codes = status_codes.uniq
36
+ if status_codes.size == 1
37
+ output_message.status_code = status_codes.first
38
+ else
39
+ output_message.status_code = MessageProcessingError::STATUS_CODE
40
+ end
41
+
42
+ output_message.body = errors.values.first["body"]
43
+ else
44
+ output_message.body.delete("errors")
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2013 Droonga Project
1
+ # Copyright (C) 2013-2014 Droonga Project
4
2
  #
5
3
  # This library is free software; you can redistribute it and/or
6
4
  # modify it under the terms of the GNU Lesser General Public
@@ -16,18 +14,16 @@
16
14
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
15
 
18
16
  require "droonga/plugin"
17
+ require "droonga/plugins/groonga/generic_response"
18
+ require "droonga/plugins/groonga/select"
19
+ require "droonga/plugins/groonga/table_create"
20
+ require "droonga/plugins/groonga/table_remove"
21
+ require "droonga/plugins/groonga/column_create"
19
22
 
20
23
  module Droonga
21
- class OutputAdapterPlugin < Plugin
22
- extend PluginRegisterable
23
-
24
- def initialize(dispatcher)
25
- super()
26
- @dispatcher = dispatcher
27
- end
28
-
29
- def forward(message, destination)
30
- @dispatcher.forward(message, destination)
24
+ module Plugins
25
+ module Groonga
26
+ Plugin.registry.register("groonga", self)
31
27
  end
32
28
  end
33
29
  end
@@ -0,0 +1,123 @@
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
+ require "groonga/command/column-create"
17
+
18
+ require "droonga/plugin"
19
+ require "droonga/plugins/groonga/generic_command"
20
+
21
+ module Droonga
22
+ module Plugins
23
+ module Groonga
24
+ module ColumnCreate
25
+ class Command < GenericCommand
26
+ def process_request(request)
27
+ command_class = ::Groonga::Command.find("column_create")
28
+ @command = command_class.new("column_create", request)
29
+
30
+ table_name = @command["table"]
31
+ if table_name.nil? || @context[table_name].nil?
32
+ message = "table doesn't exist: <#{table_name.to_s}>"
33
+ raise CommandError.new(:status => Status::INVALID_ARGUMENT,
34
+ :message => message,
35
+ :result => false)
36
+ end
37
+
38
+ if @command.column_index?
39
+ define_index
40
+ else
41
+ define_column
42
+ end
43
+ end
44
+
45
+ private
46
+ def define_column
47
+ table_name = @command["table"]
48
+ column_name = @command["name"]
49
+ column_type = @command["type"]
50
+
51
+ options = create_column_options
52
+ ::Groonga::Schema.define(:context => @context) do |schema|
53
+ schema.change_table(table_name) do |table|
54
+ table.column(column_name, column_type, options)
55
+ end
56
+ end
57
+ true
58
+ end
59
+
60
+ def create_column_options
61
+ options = {}
62
+ create_column_options_flags(options)
63
+ options
64
+ end
65
+
66
+ def create_column_options_flags(options)
67
+ options[:type] = :scalar
68
+ if @command.column_scalar?
69
+ options[:type] = :scalar
70
+ elsif @command.column_vector?
71
+ options[:type] = :vector
72
+ end
73
+ options
74
+ end
75
+
76
+ def define_index
77
+ table_name = @command["table"]
78
+ target_table = @command["type"]
79
+ target_columns = (@command["source"] || "").split(/\s*,\s*/)
80
+
81
+ options = create_index_options
82
+ ::Groonga::Schema.define(:context => @context) do |schema|
83
+ schema.change_table(table_name) do |table|
84
+ arguments = [target_table, *target_columns]
85
+ arguments << options
86
+ table.index(*arguments)
87
+ end
88
+ end
89
+ true
90
+ end
91
+
92
+ def create_index_options
93
+ options = {}
94
+ create_index_options_name(options)
95
+ create_index_options_flags(options)
96
+ options
97
+ end
98
+
99
+ def create_index_options_name(options)
100
+ options[:name] = @command["name"]
101
+ end
102
+
103
+ def create_index_options_flags(options)
104
+ options[:with_section] = true if @command.with_section?
105
+ options[:with_weight] = true if @command.with_weight?
106
+ options[:with_position] = true if @command.with_position?
107
+ end
108
+ end
109
+
110
+ class Handler < Droonga::Handler
111
+ message.type = "column_create"
112
+ action.synchronous = true
113
+
114
+ def handle(message, messenger)
115
+ command = Command.new(@context)
116
+ outputs = command.execute(message.request)
117
+ messenger.emit(outputs)
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end