Kouhei Sutou
null+****@clear*****
Fri Feb 7 18:48:30 JST 2014
Kouhei Sutou 2014-02-07 18:48:30 +0900 (Fri, 07 Feb 2014) New Revision: 18b2cb23b43c61f03c697ea44839742b67b4d9f0 https://github.com/droonga/fluent-plugin-droonga/commit/18b2cb23b43c61f03c697ea44839742b67b4d9f0 Message: Migrate Handler to new plugin style Note: This is not stable API yet. Before: # lib/droonga/plugin/handler/my_handler.rb require "droonga/handler_plugin" module Droonga class MyHandler < Droonga::HandlerPlugin repository.register("my-handler", self) command :my_command def my_command(message, messenger) end end end After: # lib/droonga/plugins/my_plugin.rb require "droonga/plugin" module Droonga module Plugins module MyPlugin Plugin.registry.register("my-plugin", self) class Handler < Droonga::Handler message.type = "my-command" def handle(message, messenger) end end end end end Added files: lib/droonga/plugins/groonga/column_create.rb lib/droonga/plugins/groonga/generic_command.rb lib/droonga/plugins/groonga/table_create.rb lib/droonga/plugins/groonga/table_remove.rb lib/droonga/plugins/watch.rb Copied files: lib/droonga/plugin/metadata/handler_action.rb (from lib/droonga/plugin.rb) lib/droonga/plugin/metadata/input_message.rb (from lib/droonga/plugin.rb) lib/droonga/plugins/search.rb (from lib/droonga/plugins/crud.rb) Removed files: lib/droonga/plugin/handler/add.rb lib/droonga/plugin/handler/forward.rb lib/droonga/plugin/handler/groonga.rb lib/droonga/plugin/handler/groonga/column_create.rb lib/droonga/plugin/handler/groonga/table_create.rb lib/droonga/plugin/handler/groonga/table_remove.rb lib/droonga/plugin/handler/watch.rb Modified files: lib/droonga/catalog/base.rb lib/droonga/handler_runner.rb lib/droonga/plugin.rb lib/droonga/plugins/crud.rb lib/droonga/plugins/groonga.rb sample/cluster/catalog.json test/command/config/default/catalog.json test/unit/catalog/test_version1.rb Renamed files: lib/droonga/handler.rb (from lib/droonga/plugin/handler/search.rb) lib/droonga/plugins/groonga/generic_response.rb (from lib/droonga/plugins/groonga/generic.rb) test/unit/plugins/crud/test_add.rb (from test/unit/plugin/handler/test_add.rb) test/unit/plugins/groonga/test_column_create.rb (from test/unit/plugin/handler/groonga/test_column_create.rb) test/unit/plugins/groonga/test_table_create.rb (from test/unit/plugin/handler/groonga/test_table_create.rb) test/unit/plugins/groonga/test_table_remove.rb (from test/unit/plugin/handler/groonga/test_table_remove.rb) test/unit/plugins/test_groonga.rb (from test/unit/plugin/handler/test_groonga.rb) test/unit/plugins/test_search.rb (from test/unit/plugin/handler/test_search.rb) test/unit/plugins/test_watch.rb (from test/unit/plugin/handler/test_watch.rb) Modified: lib/droonga/catalog/base.rb (+2 -3) =================================================================== --- lib/droonga/catalog/base.rb 2014-02-07 18:29:19 +0900 (abe6f34) +++ lib/droonga/catalog/base.rb 2014-02-07 18:48:30 +0900 (1865758) @@ -54,8 +54,7 @@ module Droonga results = {} @data["datasets"].each do |key, dataset| workers = dataset["workers"] - handler = dataset["handler"] || {} - plugins = handler["plugins"] || dataset["plugins"] + plugins = dataset["plugins"] dataset["ring"].each do |key, part| part["partitions"].each do |range, partitions| partitions.each do |partition| @@ -65,7 +64,7 @@ module Droonga options = { :database => path, :n_workers => workers, - :handlers => plugins + :plugins => plugins } results[partition] = options end Renamed: lib/droonga/handler.rb (+21 -16) 56% =================================================================== --- lib/droonga/plugin/handler/search.rb 2014-02-07 18:29:19 +0900 (f7468de) +++ lib/droonga/handler.rb 2014-02-07 18:48:30 +0900 (145381d) @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013 Droonga Project +# Copyright (C) 2014 Droonga Project # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -15,23 +13,30 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -require "droonga/handler_plugin" -require "droonga/searcher" +require "droonga/pluggable" +require "droonga/plugin/metadata/input_message" +require "droonga/plugin/metadata/handler_action" module Droonga - class SearchHandler < Droonga::HandlerPlugin - repository.register("search", self) + class Handler + extend Pluggable + + class << self + def message + Plugin::Metadata::InputMessage.new(self) + end - command :search - def search(message, messenger) - searcher = Droonga::Searcher.new(@context) - values = {} - request = message.request - raise Droonga::Searcher::NoQuery.new unless request - searcher.search(request["queries"]).each do |output, value| - values[output] = value + def action + Plugin::Metadata::HandlerAction.new(self) end - messenger.emit(values) + end + + def initialize(name, context) + @name = name + @context = context + end + + def handle(message, messenger) end end end Modified: lib/droonga/handler_runner.rb (+23 -18) =================================================================== --- lib/droonga/handler_runner.rb 2014-02-07 18:29:19 +0900 (38c0a87) +++ lib/droonga/handler_runner.rb 2014-02-07 18:48:30 +0900 (517c47c) @@ -18,15 +18,10 @@ require "groonga" require "droonga/forwarder" require "droonga/handler_message" require "droonga/handler_messenger" -require "droonga/legacy_pluggable" -require "droonga/handler_plugin" +require "droonga/handler" module Droonga class HandlerRunner - include LegacyPluggable - - attr_reader :context, :name - def initialize(loop, options={}) @loop = loop @options = options @@ -43,7 +38,6 @@ module Droonga def shutdown $log.trace("#{log_tag}: shutdown: start") - super @forwarder.shutdown if @database @database.close @@ -54,20 +48,24 @@ module Droonga end def prefer_synchronous?(command) - find_plugin(command).prefer_synchronous?(command) + find_handler_class(command).action.synchronous? + end + + def processable?(command) + not find_handler_class(command).nil? end def process(message) $log.trace("#{log_tag}: process: start") command = message["type"] - plugin = find_plugin(command) - if plugin.nil? - $log.trace("#{log_tag}: process: done: no plugin: <#{command}>") + handler_class = find_handler_class(command) + if handler_class.nil? + $log.trace("#{log_tag}: process: done: no handler: <#{command}>") return end - process_command(plugin, command, message) + process_command(handler_class, command, message) $log.trace("#{log_tag}: process: done: <#{command}>", - :plugin => plugin.class) + :handler => handler_class) end private @@ -76,20 +74,27 @@ module Droonga @context = Groonga::Context.new @database =****@conte*****_database(@database_name) end - load_plugins(@options[:handlers] || []) + @handler_classes = Handler.find_sub_classes(@options[:plugins] || []) @forwarder = Forwarder.new(@loop) end - def instantiate_plugin(name) - HandlerPlugin.repository.instantiate(name, self) + def find_handler_class(command) + @handler_classes.find do |handler_class| + handler_class.message.type == command + end end - def process_command(plugin, command, raw_message) + def process_command(handler_class, command, raw_message) handler_message = HandlerMessage.new(raw_message) handler_message.validate messenger = HandlerMessenger.new(@forwarder, handler_message, @options) - plugin.process(command, handler_message, messenger) + handler = handler_class.new(@name, @context) + begin + handler.handle(handler_message, messenger) + rescue MessageProcessingError => error + messenger.error(error.status_code, error.response_body) + end end def log_tag Modified: lib/droonga/plugin.rb (+1 -0) =================================================================== --- lib/droonga/plugin.rb 2014-02-07 18:29:19 +0900 (578522a) +++ lib/droonga/plugin.rb 2014-02-07 18:48:30 +0900 (9f1d085) @@ -15,6 +15,7 @@ require "droonga/plugin_registry" require "droonga/adapter" +require "droonga/handler" module Droonga module Plugin Deleted: lib/droonga/plugin/handler/add.rb (+0 -109) 100644 =================================================================== --- lib/droonga/plugin/handler/add.rb 2014-02-07 18:29:19 +0900 (662b9b7) +++ /dev/null @@ -1,109 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013 Droonga Project -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License version 2.1 as published by the Free Software Foundation. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -require "groonga" - -require "droonga/handler_plugin" -require "droonga/message_processing_error" - -module Droonga - class AddHandler < Droonga::HandlerPlugin - repository.register("add", self) - - class MissingTableParameter < BadRequest - def initialize - super("\"table\" must be specified.") - end - end - - class MissingPrimaryKeyParameter < BadRequest - def initialize(table_name) - super("\"key\" must be specified. " + - "The table #{table_name.inspect} requires a primary key for a new record.") - end - end - - class UnknownTable < NotFound - def initialize(table_name) - super("The table #{table_name.inspect} does not exist in the dataset.") - end - end - - class InvalidValue < BadRequest - def initialize(column, value, request) - super("The column #{column.inspect} cannot store the value #{value.inspect}.", - request) - end - end - - class UnknownColumn < NotFound - def initialize(column, table, request) - super("The column #{column.inspect} does not exist in the table #{table.inspect}.", - request) - end - end - - command :add - def add(message, messenger) - succeeded = process_add(message.request) - outputs = { - "success" => succeeded, - } - messenger.emit(outputs) - end - - private - def process_add(request) - raise MissingTableParameter.new unless request.include?("table") - - table = @context[request["table"]] - raise UnknownTable.new(request["table"]) unless table - - if table.support_key? - unless request.include?("key") - raise MissingPrimaryKeyParameter.new(request["table"]) - end - end - - add_record(table, request) - true - end - - def add_record(table, request) - record = nil - if table.support_key? - record = table.add(request["key"]) - else - record = table.add - end - (request["values"] || []).each do |column, value| - begin - record[column] = value - rescue Groonga::InvalidArgument => error - record.delete if record.added? - raise InvalidValue.new(column, value, request) - rescue ArgumentError => error - record.delete if record.added? - raise InvalidValue.new(column, value, request) - rescue Groonga::NoSuchColumn => error - record.delete if record.added? - raise UnknownColumn.new(column, request["table"], request) - end - end - end - end -end Deleted: lib/droonga/plugin/handler/forward.rb (+0 -75) 100644 =================================================================== --- lib/droonga/plugin/handler/forward.rb 2014-02-07 18:29:19 +0900 (928207c) +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013 Droonga Project -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License version 2.1 as published by the Free Software Foundation. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -=begin - -TODO: What is this? - -require "droonga/legacy_plugin" -require "droonga/logger" - -module Droonga - class MergeHandler < Droonga::LegacyPlugin - Droonga::LegacyPlugin.repository.register("forward", self) - - CONFIG_FILE_PATH = 'config.json' - - def handlable?(command) - true - end - - def handle(command, request, *arguments) - destination = get_destination - post(request, - "to" => destination, "type" => command, "arguments" => arguments) - rescue => exception - Logger.error("error while handling #{command}", - request: request, - arguments: arguments, - exception: exception) - end - - def get_destination - loop do - refresh_config - if @config && @config["forward"] - path =****@conte***** - destination = @config["forward"][path] - return destination unless destination.nil? || destination.empty? - end - sleep 5 - end - end - - def refresh_config - unless File.exists?(CONFIG_FILE_PATH) - @config = nil - return - end - mtime = File.mtime(CONFIG_FILE_PATH) - return if @config_mtime == mtime - open(CONFIG_FILE_PATH) do |file| - @config = JSON.parse(file.read) - end - @config_mtime = mtime - rescue => exception - Logger.error("error while refreshing config", exception: exception) - @config = nil - end - end -end -=end Deleted: lib/droonga/plugin/handler/groonga.rb (+0 -99) 100644 =================================================================== --- lib/droonga/plugin/handler/groonga.rb 2014-02-07 18:29:19 +0900 (959bcd0) +++ /dev/null @@ -1,99 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013 Droonga Project -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License version 2.1 as published by the Free Software Foundation. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -require "groonga" - -require "droonga/handler_plugin" - -module Droonga - class GroongaHandler < Droonga::HandlerPlugin - repository.register("groonga", self) - - command :table_create - def table_create(message, messenger) - command = TableCreate.new(@context) - outputs = format_outputs(command.execute(message.request)) - messenger.emit(outputs) - end - - command :table_remove - def table_remove(message, messenger) - command = TableRemove.new(@context) - outputs = format_outputs(command.execute(message.request)) - messenger.emit(outputs) - end - - command :column_create - def column_create(message, messenger) - command = ColumnCreate.new(@context) - outputs = format_outputs(command.execute(message.request)) - messenger.emit(outputs) - end - - def prefer_synchronous?(command) - return true - end - - private - def format_outputs(result) - { - "result" => result, - } - end - - module Status - SUCCESS = 0 - INVALID_ARGUMENT = -22 - end - - class Command - class CommandError < StandardError - attr_reader :status, :message, :result - - def initialize(params={}) - @status = params[:status] - @message = params[:message] - @result = params[:result] - end - end - - def initialize(context) - @context = context - end - - def execute(request) - @start_time = Time.now.to_f - result = process_request(request) - [header(Status::SUCCESS), result] - rescue CommandError => error - [header(error.status, error.message), error.result] - end - - private - def header(return_code, error_message="") - elapsed_time = Time.now.to_f - @start_time - header = [return_code, @start_time, elapsed_time] - header.push(error_message) unless error_message.empty? - header - end - end - end -end - -require "droonga/plugin/handler/groonga/table_create" -require "droonga/plugin/handler/groonga/table_remove" -require "droonga/plugin/handler/groonga/column_create" Deleted: lib/droonga/plugin/handler/groonga/column_create.rb (+0 -108) 100644 =================================================================== --- lib/droonga/plugin/handler/groonga/column_create.rb 2014-02-07 18:29:19 +0900 (16c25ce) +++ /dev/null @@ -1,108 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013 Droonga Project -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License version 2.1 as published by the Free Software Foundation. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -require "groonga" -require "groonga/command/column-create" - -module Droonga - class GroongaHandler - class ColumnCreate < Command - def process_request(request) - command_class = Groonga::Command.find("column_create") - @command = command_class.new("column_create", request) - - table_name = @command["table"] - if table_name.nil? || @context[table_name].nil? - raise CommandError.new(:status => Status::INVALID_ARGUMENT, - :message => "table doesn't exist: <#{table_name.to_s}>", - :result => false) - end - - if****@comma*****_index? - define_index - else - define_column - end - end - - private - def define_column - table_name = @command["table"] - column_name = @command["name"] - column_type = @command["type"] - - options = create_column_options - Groonga::Schema.define(:context => @context) do |schema| - schema.change_table(table_name) do |table| - table.column(column_name, column_type, options) - end - end - true - end - - def create_column_options - options = {} - create_column_options_flags(options) - options - end - - def create_column_options_flags(options) - options[:type] = :scalar - if****@comma*****_scalar? - options[:type] = :scalar - elsif****@comma*****_vector? - options[:type] = :vector - end - options - end - - def define_index - table_name = @command["table"] - target_table = @command["type"] - target_columns = (@command["source"] || "").split(/\s*,\s*/) - - options = create_index_options - Groonga::Schema.define(:context => @context) do |schema| - schema.change_table(table_name) do |table| - arguments = [target_table, *target_columns] - arguments << options - table.index(*arguments) - end - end - true - end - - def create_index_options - options = {} - create_index_options_name(options) - create_index_options_flags(options) - options - end - - def create_index_options_name(options) - options[:name] = @command["name"] - end - - def create_index_options_flags(options) - options[:with_section] = true if****@comma*****_section? - options[:with_weight] = true if****@comma*****_weight? - options[:with_position] = true if****@comma*****_position? - options - end - end - end -end Deleted: lib/droonga/plugin/handler/groonga/table_create.rb (+0 -91) 100644 =================================================================== --- lib/droonga/plugin/handler/groonga/table_create.rb 2014-02-07 18:29:19 +0900 (6b69330) +++ /dev/null @@ -1,91 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013 Droonga Project -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License version 2.1 as published by the Free Software Foundation. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -require "groonga" -require "groonga/command/table-create" - -module Droonga - class GroongaHandler - class TableCreate < Command - def process_request(request) - command_class = Groonga::Command.find("table_create") - @command = command_class.new("table_create", request) - - name = @command["name"] - unless name - raise CommandError.new(:status => Status::INVALID_ARGUMENT, - :message => "Should not create anonymous table", - :result => false) - end - - options = parse_command - Groonga::Schema.define(:context => @context) do |schema| - schema.create_table(name, options) - end - true - end - - private - def parse_command - options = {} - parse_flags(options) - parse_key_type(options) - parse_value_type(options) - parse_default_tokenizer(options) - parse_normalizer(options) - options - end - - def parse_flags(options) - options[:type] = :hash - if****@comma*****_no_key? - options[:type] = :array - elsif****@comma*****_hash_key? - options[:type] = :hash - elsif****@comma*****_pat_key? - options[:type] = :patricia_trie - elsif****@comma*****_dat_key? - options[:type] = :double_array_trie - end - if****@comma*****_with_sis? and****@comma*****_pat_key? - options[:key_with_sis] = true - end - options - end - - def parse_key_type(options) - options[:key_type] = @command["key_type"] if @command["key_type"] - options - end - - def parse_value_type(options) - options[:value_type] = @command["value_type"] if @command["value_type"] - options - end - - def parse_default_tokenizer(options) - options[:default_tokenizer] = @command["default_tokenizer"] if @command["default_tokenizer"] - options - end - - def parse_normalizer(options) - options[:normalizer] = @command["normalizer"] if @command["normalizer"] - options - end - end - end -end Deleted: lib/droonga/plugin/handler/groonga/table_remove.rb (+0 -42) 100644 =================================================================== --- lib/droonga/plugin/handler/groonga/table_remove.rb 2014-02-07 18:29:19 +0900 (24dd536) +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2014 Droonga Project -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License version 2.1 as published by the Free Software Foundation. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -require "groonga" -require "groonga/command/table-remove" - -module Droonga - class GroongaHandler - class TableRemove < Command - def process_request(request) - command_class = Groonga::Command.find("table_remove") - @command = command_class.new("table_remove", request) - - name = @command["name"] - if name.nil? || @context[name].nil? - raise CommandError.new(:status => Status::INVALID_ARGUMENT, - :message => "table not found", - :result => false) - end - - Groonga::Schema.define(:context => @context) do |schema| - schema.remove_table(name) - end - true - end - end - end -end Deleted: lib/droonga/plugin/handler/watch.rb (+0 -114) 100644 =================================================================== --- lib/droonga/plugin/handler/watch.rb 2014-02-07 18:29:19 +0900 (21866ee) +++ /dev/null @@ -1,114 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013 Droonga Project -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License version 2.1 as published by the Free Software Foundation. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -require "droonga/watcher" -require "droonga/sweeper" -require "droonga/watch_schema" -require "droonga/handler_plugin" - -module Droonga - class WatchHandler < Droonga::HandlerPlugin - repository.register("watch", self) - - def initialize(*args) - super - - # XXX just workaround. This must be re-written. - # When secondary and later processes opens the database, - # creation processes of tables by the first process is - # not finished yet. Then secondary and others tries to - # create tables and raises errors. To avoid such a problem, - # the creation processes of tables is disabled on workers. - if $0 !~ /\AServer/ - ensure_schema_created - else - until @context["Keyword"] - sleep 0.1 - end - sleep 1 - end - - @watcher = Watcher.new(@context) - @sweeper = Sweeper.new(@context) - end - - command "watch.subscribe" => :subscribe - def subscribe(message, messenger) - subscriber, condition, query, route = parse_message(message) - normalized_request = { - :subscriber => subscriber, - :condition => condition, - :query => query, - :route => route, - } - @watcher.subscribe(normalized_request) - outputs = { - "success" => true, - } - messenger.emit(outputs) - end - - command "watch.unsubscribe" => :unsubscribe - def unsubscribe(message, messenger) - subscriber, condition, query, route = parse_message(message) - normalized_request = { - :subscriber => subscriber, - :condition => condition, - :query => query, - } - @watcher.unsubscribe(normalized_request) - outputs = { - "success" => true, - } - messenger.emit(outputs) - end - - command "watch.feed" => :feed - def feed(message, messenger) - request = message.request - @watcher.feed(:targets => request["targets"]) do |route, subscribers| - published_message = { - "to" => subscribers, - "body" => request, - } - published_message = message.raw.merge(published_message) - messenger.forward(published_message, - "to" => route, "type" => "watch.publish") - end - end - - command "watch.sweep" => :sweep - def sweep(message, messenger) - @sweeper.sweep_expired_subscribers - end - - private - def parse_message(message) - request = message.request - subscriber = request["subscriber"] - condition = request["condition"] - route = request["route"] || message["from"] - query = condition && condition.to_json - [subscriber, condition, query, route] - end - - def ensure_schema_created - schema = WatchSchema.new(@context) - schema.ensure_created - end - end -end Copied: lib/droonga/plugin/metadata/handler_action.rb (+18 -6) 64% =================================================================== --- lib/droonga/plugin.rb 2014-02-07 18:29:19 +0900 (578522a) +++ lib/droonga/plugin/metadata/handler_action.rb 2014-02-07 18:48:30 +0900 (3cbd692) @@ -13,14 +13,26 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -require "droonga/plugin_registry" -require "droonga/adapter" - module Droonga module Plugin - class << self - def registry - @@registry ||= PluginRegistry.new + module Metadata + class HandlerAction + def initialize(handler_class) + @handler_class = handler_class + end + + def synchronous? + configuration[:synchronous] + end + + def synchronous=(boolean) + configuration[:synchronous] = boolean + end + + private + def configuration + @handler_class.options[:action] ||= {} + end end end end Copied: lib/droonga/plugin/metadata/input_message.rb (+18 -6) 67% =================================================================== --- lib/droonga/plugin.rb 2014-02-07 18:29:19 +0900 (578522a) +++ lib/droonga/plugin/metadata/input_message.rb 2014-02-07 18:48:30 +0900 (ca18c80) @@ -13,14 +13,26 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -require "droonga/plugin_registry" -require "droonga/adapter" - module Droonga module Plugin - class << self - def registry - @@registry ||= PluginRegistry.new + module Metadata + class InputMessage + def initialize(plugin_class) + @plugin_class = plugin_class + end + + def type + configuration[:type] + end + + def type=(type) + configuration[:type] = type + end + + private + def configuration + @plugin_class.options[:message] ||= {} + end end end end Modified: lib/droonga/plugins/crud.rb (+88 -0) =================================================================== --- lib/droonga/plugins/crud.rb 2014-02-07 18:29:19 +0900 (9842787) +++ lib/droonga/plugins/crud.rb 2014-02-07 18:48:30 +0900 (316930b) @@ -13,7 +13,10 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +require "groonga" + require "droonga/plugin" +require "droonga/message_processing_error" module Droonga module Plugins @@ -31,6 +34,91 @@ module Droonga end end end + + class Handler < Droonga::Handler + message.type = "add" + + class MissingTableParameter < BadRequest + def initialize + super("\"table\" must be specified.") + end + end + + class MissingPrimaryKeyParameter < BadRequest + def initialize(table_name) + super("\"key\" must be specified. " + + "The table #{table_name.inspect} requires a primary key for a new record.") + end + end + + class UnknownTable < NotFound + def initialize(table_name) + super("The table #{table_name.inspect} does not exist in the dataset.") + end + end + + class InvalidValue < BadRequest + def initialize(column, value, request) + super("The column #{column.inspect} cannot store the value #{value.inspect}.", + request) + end + end + + class UnknownColumn < NotFound + def initialize(column, table, request) + super("The column #{column.inspect} does not exist in the table #{table.inspect}.", + request) + end + end + + def handle(message, messenger) + succeeded = process_add(message.request) + outputs = { + "success" => succeeded, + } + messenger.emit(outputs) + end + + private + def process_add(request) + raise MissingTableParameter.new unless request.include?("table") + + table = @context[request["table"]] + raise UnknownTable.new(request["table"]) unless table + + if table.support_key? + unless request.include?("key") + raise MissingPrimaryKeyParameter.new(request["table"]) + end + end + + add_record(table, request) + true + end + + def add_record(table, request) + record = nil + if table.support_key? + record = table.add(request["key"]) + else + record = table.add + end + (request["values"] || []).each do |column, value| + begin + record[column] = value + rescue ::Groonga::InvalidArgument => error + record.delete if record.added? + raise InvalidValue.new(column, value, request) + rescue ArgumentError => error + record.delete if record.added? + raise InvalidValue.new(column, value, request) + rescue ::Groonga::NoSuchColumn => error + record.delete if record.added? + raise UnknownColumn.new(column, request["table"], request) + end + end + end + end end end end Modified: lib/droonga/plugins/groonga.rb (+4 -1) =================================================================== --- lib/droonga/plugins/groonga.rb 2014-02-07 18:29:19 +0900 (4429c4b) +++ lib/droonga/plugins/groonga.rb 2014-02-07 18:48:30 +0900 (9cd6b7e) @@ -14,8 +14,11 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA require "droonga/plugin" -require "droonga/plugins/groonga/generic" +require "droonga/plugins/groonga/generic_response" require "droonga/plugins/groonga/select" +require "droonga/plugins/groonga/table_create" +require "droonga/plugins/groonga/table_remove" +require "droonga/plugins/groonga/column_create" module Droonga module Plugins Added: lib/droonga/plugins/groonga/column_create.rb (+123 -0) 100644 =================================================================== --- /dev/null +++ lib/droonga/plugins/groonga/column_create.rb 2014-02-07 18:48:30 +0900 (3772f1f) @@ -0,0 +1,123 @@ +# Copyright (C) 2013-2014 Droonga Project +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +require "groonga/command/column-create" + +require "droonga/plugin" +require "droonga/plugins/groonga/generic_command" + +module Droonga + module Plugins + module Groonga + module ColumnCreate + class Command < GenericCommand + def process_request(request) + command_class = ::Groonga::Command.find("column_create") + @command = command_class.new("column_create", request) + + table_name = @command["table"] + if table_name.nil? || @context[table_name].nil? + message = "table doesn't exist: <#{table_name.to_s}>" + raise CommandError.new(:status => Status::INVALID_ARGUMENT, + :message => message, + :result => false) + end + + if****@comma*****_index? + define_index + else + define_column + end + end + + private + def define_column + table_name = @command["table"] + column_name = @command["name"] + column_type = @command["type"] + + options = create_column_options + ::Groonga::Schema.define(:context => @context) do |schema| + schema.change_table(table_name) do |table| + table.column(column_name, column_type, options) + end + end + true + end + + def create_column_options + options = {} + create_column_options_flags(options) + options + end + + def create_column_options_flags(options) + options[:type] = :scalar + if****@comma*****_scalar? + options[:type] = :scalar + elsif****@comma*****_vector? + options[:type] = :vector + end + options + end + + def define_index + table_name = @command["table"] + target_table = @command["type"] + target_columns = (@command["source"] || "").split(/\s*,\s*/) + + options = create_index_options + ::Groonga::Schema.define(:context => @context) do |schema| + schema.change_table(table_name) do |table| + arguments = [target_table, *target_columns] + arguments << options + table.index(*arguments) + end + end + true + end + + def create_index_options + options = {} + create_index_options_name(options) + create_index_options_flags(options) + options + end + + def create_index_options_name(options) + options[:name] = @command["name"] + end + + def create_index_options_flags(options) + options[:with_section] = true if****@comma*****_section? + options[:with_weight] = true if****@comma*****_weight? + options[:with_position] = true if****@comma*****_position? + end + end + + class Handler < Droonga::Handler + message.type = "column_create" + action.synchronous = true + + def handle(message, messenger) + command = Command.new(@context) + outputs = command.execute(message.request) + messenger.emit(outputs) + end + end + end + end + end +end Added: lib/droonga/plugins/groonga/generic_command.rb (+65 -0) 100644 =================================================================== --- /dev/null +++ lib/droonga/plugins/groonga/generic_command.rb 2014-02-07 18:48:30 +0900 (8d21581) @@ -0,0 +1,65 @@ +# Copyright (C) 2013-2014 Droonga Project +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +require "groonga" + +module Droonga + module Plugins + module Groonga + module Status + SUCCESS = 0 + INVALID_ARGUMENT = -22 + end + + class GenericCommand + class CommandError < StandardError + attr_reader :status, :message, :result + + def initialize(params={}) + @status = params[:status] + @message = params[:message] + @result = params[:result] + end + end + + def initialize(context) + @context = context + end + + def execute(request) + @start_time = Time.now.to_f + result = process_request(request) + format(header(Status::SUCCESS), result) + rescue CommandError => error + format(header(error.status, error.message), error.result) + end + + private + def header(return_code, error_message="") + elapsed_time = Time.now.to_f - @start_time + header = [return_code, @start_time, elapsed_time] + header.push(error_message) unless error_message.empty? + header + end + + def format(header, body) + { + "result" => [header, body], + } + end + end + end + end +end Renamed: lib/droonga/plugins/groonga/generic_response.rb (+0 -0) 100% =================================================================== Added: lib/droonga/plugins/groonga/table_create.rb (+106 -0) 100644 =================================================================== --- /dev/null +++ lib/droonga/plugins/groonga/table_create.rb 2014-02-07 18:48:30 +0900 (3e2e1f0) @@ -0,0 +1,106 @@ +# Copyright (C) 2013-2014 Droonga Project +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +require "groonga/command/table-create" + +require "droonga/plugin" +require "droonga/plugins/groonga/generic_command" + +module Droonga + module Plugins + module Groonga + module TableCreate + class Command < GenericCommand + def process_request(request) + command_class = ::Groonga::Command.find("table_create") + @command = command_class.new("table_create", request) + + name = @command["name"] + unless name + message = "Should not create anonymous table" + raise CommandError.new(:status => Status::INVALID_ARGUMENT, + :message => message, + :result => false) + end + + options = parse_command + ::Groonga::Schema.define(:context => @context) do |schema| + schema.create_table(name, options) + end + true + end + + private + def parse_command + options = {} + parse_flags(options) + parse_key_type(options) + parse_value_type(options) + parse_default_tokenizer(options) + parse_normalizer(options) + options + end + + def parse_flags(options) + options[:type] = :hash + if****@comma*****_no_key? + options[:type] = :array + elsif****@comma*****_hash_key? + options[:type] = :hash + elsif****@comma*****_pat_key? + options[:type] = :patricia_trie + elsif****@comma*****_dat_key? + options[:type] = :double_array_trie + end + if****@comma*****_with_sis? and****@comma*****_pat_key? + options[:key_with_sis] = true + end + end + + def parse_key_type(options) + return unless @command["key_type"] + options[:key_type] = @command["key_type"] + end + + def parse_value_type(options) + return unless @command["value_type"] + options[:value_type] = @command["value_type"] + end + + def parse_default_tokenizer(options) + return unless @command["default_tokenizer"] + options[:default_tokenizer] = @command["default_tokenizer"] + end + + def parse_normalizer(options) + return unless @command["normalizer"] + options[:normalizer] = @command["normalizer"] + end + end + + class Handler < Droonga::Handler + message.type = "table_create" + action.synchronous = true + + def handle(message, messenger) + command = Command.new(@context) + outputs = command.execute(message.request) + messenger.emit(outputs) + end + end + end + end + end +end Added: lib/droonga/plugins/groonga/table_remove.rb (+57 -0) 100644 =================================================================== --- /dev/null +++ lib/droonga/plugins/groonga/table_remove.rb 2014-02-07 18:48:30 +0900 (b1b1815) @@ -0,0 +1,57 @@ +# Copyright (C) 2014 Droonga Project +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +require "groonga/command/table-remove" + +require "droonga/plugin" +require "droonga/plugins/groonga/generic_command" + +module Droonga + module Plugins + module Groonga + module TableRemove + class Command < GenericCommand + def process_request(request) + command_class = ::Groonga::Command.find("table_remove") + @command = command_class.new("table_remove", request) + + name = @command["name"] + if name.nil? || @context[name].nil? + raise CommandError.new(:status => Status::INVALID_ARGUMENT, + :message => "table not found", + :result => false) + end + + ::Groonga::Schema.define(:context => @context) do |schema| + schema.remove_table(name) + end + true + end + end + + class Handler < Droonga::Handler + message.type = "table_remove" + action.synchronous = true + + def handle(message, messenger) + command = Command.new(@context) + outputs = command.execute(message.request) + messenger.emit(outputs) + end + end + end + end + end +end Copied: lib/droonga/plugins/search.rb (+13 -9) 61% =================================================================== --- lib/droonga/plugins/crud.rb 2014-02-07 18:29:19 +0900 (9842787) +++ lib/droonga/plugins/search.rb 2014-02-07 18:48:30 +0900 (84bffc1) @@ -14,21 +14,25 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA require "droonga/plugin" +require "droonga/searcher" module Droonga module Plugins - module CRUD - Plugin.registry.register("crud", self) + module Search + Plugin.registry.register("search", self) - class Adapter < Droonga::Adapter - message.input_pattern = ["type", :equal, "add"] - message.output_pattern = ["body.success", :exist?] + class Handler < Droonga::Handler + message.type = "search" - def adapt_output(output_message) - success = output_message.body["success"] - unless success.nil? - output_message.body = output_message.body["success"] + def handle(message, messenger) + searcher = Droonga::Searcher.new(@context) + values = {} + request = message.request + raise Droonga::Searcher::NoQuery.new unless request + searcher.search(request["queries"]).each do |output, value| + values[output] = value end + messenger.emit(values) end end end Added: lib/droonga/plugins/watch.rb (+156 -0) 100644 =================================================================== --- /dev/null +++ lib/droonga/plugins/watch.rb 2014-02-07 18:48:30 +0900 (4e8187f) @@ -0,0 +1,156 @@ +# Copyright (C) 2013-2014 Droonga Project +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +require "droonga/plugin" +require "droonga/watcher" +require "droonga/sweeper" +require "droonga/watch_schema" + +module Droonga + module Plugins + module Watch + Plugin.registry.register("watch", self) + + module SchemaCreatable + private + def ensure_schema_created + # XXX just workaround. This must be re-written. + # When secondary and later processes opens the database, + # creation processes of tables by the first process is + # not finished yet. Then secondary and others tries to + # create tables and raises errors. To avoid such a problem, + # the creation processes of tables is disabled on workers. + if $0 !~ /\AServer/ + schema = WatchSchema.new(@context) + schema.ensure_created + else + until @context["Keyword"] + sleep 0.1 + end + sleep 1 + end + end + end + + module MessageParsable + private + def parse_message(message) + request = message.request + subscriber = request["subscriber"] + condition = request["condition"] + route = request["route"] || message["from"] + query = condition && condition.to_json + [subscriber, condition, query, route] + end + end + + class SubscribeHandler < Droonga::Handler + include SchemaCreatable + include MessageParsable + + message.type = "watch.subscribe" + + def initialize(*args) + super + ensure_schema_created # TODO: REMOVE ME + end + + def handle(message, messenger) + subscriber, condition, query, route = parse_message(message) + normalized_request = { + :subscriber => subscriber, + :condition => condition, + :query => query, + :route => route, + } + watcher = Watcher.new(@context) + watcher.subscribe(normalized_request) + outputs = { + "success" => true, + } + messenger.emit(outputs) + end + end + + class UnsubscribeHandler < Droonga::Handler + include SchemaCreatable + include MessageParsable + + message.type = "watch.unsubscribe" + + def initialize(*args) + super + ensure_schema_created # TODO: REMOVE ME + end + + def handle(message, messenger) + subscriber, condition, query, route = parse_message(message) + normalized_request = { + :subscriber => subscriber, + :condition => condition, + :query => query, + } + watcher = Watcher.new(@context) + watcher.unsubscribe(normalized_request) + outputs = { + "success" => true, + } + messenger.emit(outputs) + end + end + + class FeedHandler < Droonga::Handler + include SchemaCreatable + + message.type = "watch.feed" + + def initialize(*args) + super + ensure_schema_created # TODO: REMOVE ME + end + + def handle(message, messenger) + request = message.request + watcher = Watcher.new(@context) + watcher.feed(:targets => request["targets"]) do |route, subscribers| + published_message = { + "to" => subscribers, + "body" => request, + } + published_message = message.raw.merge(published_message) + messenger.forward(published_message, + "to" => route, "type" => "watch.publish") + end + end + end + + class SweepHandler < Droonga::Handler + include SchemaCreatable + + message.type = "watch.sweep" + + def initialize(*args) + super + ensure_schema_created # TODO: REMOVE ME + end + + def sweep(message, messenger) + sweeper = Sweeper.new(@context) + sweeper.sweep_expired_subscribers + end + end + end + end +end Modified: sample/cluster/catalog.json (+1 -4) =================================================================== --- sample/cluster/catalog.json 2014-02-07 18:29:19 +0900 (902c12b) +++ sample/cluster/catalog.json 2014-02-07 18:48:30 +0900 (6448075) @@ -11,10 +11,7 @@ "datasets": { "Droonga": { "workers": 2, - "plugins": ["crud", "groonga"], - "handler": { - "plugins": ["search", "groonga", "add"] - }, + "plugins": ["groonga", "search", "crud"], "number_of_replicas": 2, "number_of_partitions": 2, "partition_key": "_key", Modified: test/command/config/default/catalog.json (+2 -7) =================================================================== --- test/command/config/default/catalog.json 2014-02-07 18:29:19 +0900 (beeaee4) +++ test/command/config/default/catalog.json 2014-02-07 18:48:30 +0900 (0285fc8) @@ -10,10 +10,7 @@ "datasets": { "Droonga": { "workers": 2, - "handler": { - "plugins": ["search", "groonga", "add"] - }, - "plugins": ["groonga", "crud"], + "plugins": ["groonga", "crud", "search"], "number_of_replicas": 2, "number_of_partitions": 2, "partition_key": "_key", @@ -41,9 +38,7 @@ }, "Watch": { "workers": 2, - "handler": { - "plugins": ["search", "groonga", "add", "watch"] - }, + "plugins": ["groonga", "watch", "search", "crud"], "number_of_replicas": 1, "number_of_partitions": 1, "partition_key": "_key", Modified: test/unit/catalog/test_version1.rb (+8 -17) =================================================================== --- test/unit/catalog/test_version1.rb 2014-02-07 18:29:19 +0900 (850f460) +++ test/unit/catalog/test_version1.rb 2014-02-07 18:48:30 +0900 (e2465c0) @@ -55,22 +55,22 @@ class CatalogTest < Test::Unit::TestCase assert_equal({ "localhost:23003/test.000" => { :database => "#{base_path}/000/db", - :handlers => ["for_dataset"], + :plugins => ["for_dataset"], :n_workers => 0 }, "localhost:23003/test.001" => { :database => "#{base_path}/001/db", - :handlers => ["for_dataset"], + :plugins => ["for_dataset"], :n_workers => 0 }, "localhost:23003/test.002" => { :database => "#{base_path}/002/db", - :handlers => ["for_dataset"], + :plugins => ["for_dataset"], :n_workers => 0 }, "localhost:23003/test.003" => { :database => "#{base_path}/003/db", - :handlers => ["for_dataset"], + :plugins => ["for_dataset"], :n_workers => 0 }, }, @@ -89,7 +89,7 @@ class CatalogTest < Test::Unit::TestCase File.dirname(catalog_path) end - class HandlersTest < self + class PluginsTest < self def setup @data = { "farms" => { @@ -119,26 +119,17 @@ class CatalogTest < Test::Unit::TestCase "localhost:23041/droonga" end - def handlers(data) + def plugins(data) catalog = create_catalog(data, base_path) catalog.get_partitions(farm_name).collect do |partition, options| - options[:handlers] + options[:plugins] end end def test_plugins @data["datasets"]["Droonga"]["plugins"] = ["search", "groonga", "add"] assert_equal([["search", "groonga", "add"]], - handlers(@data)) - - end - - def test_handler_plugins - @data["datasets"]["Droonga"]["handler"] = { - "plugins" => ["search", "groonga", "add"], - } - assert_equal([["search", "groonga", "add"]], - handlers(@data)) + plugins(@data)) end end Renamed: test/unit/plugins/crud/test_add.rb (+11 -11) 85% =================================================================== --- test/unit/plugin/handler/test_add.rb 2014-02-07 18:29:19 +0900 (ac6aac9) +++ test/unit/plugins/crud/test_add.rb 2014-02-07 18:48:30 +0900 (0498baf) @@ -1,4 +1,4 @@ -# Copyright (C) 2013 Droonga Project +# Copyright (C) 2013-2014 Droonga Project # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -13,9 +13,9 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -require "droonga/plugin/handler/add" +require "droonga/plugins/crud" -class AddHandlerTest < Test::Unit::TestCase +class CRUDAddHandlerTest < Test::Unit::TestCase SUCCESS_RESPONSE_BODY = { "success" => true, } @@ -37,7 +37,7 @@ class AddHandlerTest < Test::Unit::TestCase def setup_handler @worker = StubWorker.new - @handler = Droonga::AddHandler.new(@worker) + @handler = Droonga::Plugins::CRUD::Handler.new("name", @worker.context) @messenger = Droonga::Test::StubHandlerMessenger.new end @@ -47,7 +47,7 @@ class AddHandlerTest < Test::Unit::TestCase def process(request) message = Droonga::Test::StubHandlerMessage.new(request) - @handler.add(message, @messenger) + @handler.handle(message, @messenger) end public @@ -93,7 +93,7 @@ class AddHandlerTest < Test::Unit::TestCase "table" => "Users", "values" => {"country" => "japan"}, } - assert_raise(Droonga::AddHandler::MissingPrimaryKeyParameter) do + assert_raise(Droonga::Plugins::CRUD::Handler::MissingPrimaryKeyParameter) do process(request) end end @@ -104,7 +104,7 @@ class AddHandlerTest < Test::Unit::TestCase "key" => "mori", "values" => {"age" => "secret"}, } - assert_raise(Droonga::AddHandler::InvalidValue) do + assert_raise(Droonga::Plugins::CRUD::Handler::InvalidValue) do process(request) end end @@ -115,7 +115,7 @@ class AddHandlerTest < Test::Unit::TestCase "key" => "mori", "values" => {"birthday" => "today"}, } - assert_raise(Droonga::AddHandler::InvalidValue) do + assert_raise(Droonga::Plugins::CRUD::Handler::InvalidValue) do process(request) end end @@ -126,7 +126,7 @@ class AddHandlerTest < Test::Unit::TestCase "key" => "mori", "values" => {"unknown" => "unknown"}, } - assert_raise(Droonga::AddHandler::UnknownColumn) do + assert_raise(Droonga::Plugins::CRUD::Handler::UnknownColumn) do process(request) end end @@ -170,7 +170,7 @@ class AddHandlerTest < Test::Unit::TestCase request = { "values" => {}, } - assert_raise(Droonga::AddHandler::MissingTableParameter) do + assert_raise(Droonga::Plugins::CRUD::Handler::MissingTableParameter) do process(request) end end @@ -180,7 +180,7 @@ class AddHandlerTest < Test::Unit::TestCase "table" => "Nonexistent", "values" => {}, } - assert_raise(Droonga::AddHandler::UnknownTable) do + assert_raise(Droonga::Plugins::CRUD::Handler::UnknownTable) do process(request) end end Renamed: test/unit/plugins/groonga/test_column_create.rb (+20 -5) 84% =================================================================== --- test/unit/plugin/handler/groonga/test_column_create.rb 2014-02-07 18:29:19 +0900 (e55a5ca) +++ test/unit/plugins/groonga/test_column_create.rb 2014-02-07 18:48:30 +0900 (3bf410d) @@ -14,8 +14,15 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA class ColumnCreateTest < GroongaHandlerTest + def create_handler + Droonga::Plugins::Groonga::ColumnCreate::Handler.new("droonga", + @handler.context) + end + def test_success - process(:table_create, {"name" => "Books"}) + Groonga::Schema.define(:context => @context) do |schema| + schema.create_table("Books", :type => :hash) + end process(:column_create, {"table" => "Books", "name" => "title", "type" => "ShortText"}) response =****@messe***** @@ -40,7 +47,9 @@ class ColumnCreateTest < GroongaHandlerTest end def test_name - process(:table_create, {"name" => "Books"}) + Groonga::Schema.define(:context => @context) do |schema| + schema.create_table("Books", :type => :hash) + end process(:column_create, {"table" => "Books", "name" => "title", "type" => "ShortText"}) assert_equal(<<-SCHEMA, dump) @@ -50,7 +59,9 @@ column_create Books title COLUMN_SCALAR ShortText end def test_type - process(:table_create, {"name" => "Books"}) + Groonga::Schema.define(:context => @context) do |schema| + schema.create_table("Books", :type => :hash) + end process(:column_create, {"table" => "Books", "name" => "main_text", "type" => "LongText"}) assert_equal(<<-SCHEMA, dump) @@ -76,7 +87,9 @@ column_create Books main_text COLUMN_SCALAR LongText "type" => "ShortText", "flags" => data[:flags], } - process(:table_create, {"name" => "Books"}) + Groonga::Schema.define(:context => @context) do |schema| + schema.create_table("Books", :type => :hash) + end process(:column_create, request) assert_equal(<<-EXPECTED, dump) table_create Books TABLE_HASH_KEY --key_type ShortText @@ -88,7 +101,9 @@ column_create Books title #{data[:flags]} ShortText class IndexTest < self def setup super - process(:table_create, {"name" => "Books"}) + Groonga::Schema.define(:context => @context) do |schema| + schema.create_table("Books", :type => :hash) + end process(:column_create, {"table" => "Books", "name" => "title", "type" => "ShortText"}) end Renamed: test/unit/plugins/groonga/test_table_create.rb (+5 -0) 96% =================================================================== --- test/unit/plugin/handler/groonga/test_table_create.rb 2014-02-07 18:29:19 +0900 (2f0820b) +++ test/unit/plugins/groonga/test_table_create.rb 2014-02-07 18:48:30 +0900 (90a2273) @@ -14,6 +14,11 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA class TableCreateTest < GroongaHandlerTest + def create_handler + Droonga::Plugins::Groonga::TableCreate::Handler.new("droonga", + @handler.context) + end + def test_success process(:table_create, {"name" => "Books"}) response =****@messe***** Renamed: test/unit/plugins/groonga/test_table_remove.rb (+8 -1) 85% =================================================================== --- test/unit/plugin/handler/groonga/test_table_remove.rb 2014-02-07 18:29:19 +0900 (3c3272e) +++ test/unit/plugins/groonga/test_table_remove.rb 2014-02-07 18:48:30 +0900 (264d074) @@ -14,9 +14,16 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA class TableRemoveTest < GroongaHandlerTest + def create_handler + Droonga::Plugins::Groonga::TableRemove::Handler.new("droonga", + @handler.context) + end + def setup super - process(:table_create, {"name" => "Books"}) + Groonga::Schema.define(:context => @context) do |schema| + schema.create_table("Books", :type => :hash) + end end def test_success Renamed: test/unit/plugins/test_groonga.rb (+5 -5) 89% =================================================================== --- test/unit/plugin/handler/test_groonga.rb 2014-02-07 18:29:19 +0900 (1abae91) +++ test/unit/plugins/test_groonga.rb 2014-02-07 18:48:30 +0900 (972f84a) @@ -13,7 +13,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -require "droonga/plugin/handler/groonga" +require "droonga/plugins/groonga" class GroongaHandlerTest < Test::Unit::TestCase include PluginHelper @@ -31,7 +31,6 @@ class GroongaHandlerTest < Test::Unit::TestCase private def setup_plugin @handler = Droonga::Test::StubHandler.new - @plugin = Droonga::GroongaHandler.new(@handler) @messenger = Droonga::Test::StubHandlerMessenger.new end @@ -45,7 +44,8 @@ class GroongaHandlerTest < Test::Unit::TestCase def process(command, request) message = Droonga::Test::StubHandlerMessage.new(request) - @plugin.send(command, message, @messenger) + handler = create_handler + handler.handle(message, @messenger) end NORMALIZED_START_TIME = Time.parse("2013-07-11T16:04:28+0900").to_i @@ -57,12 +57,12 @@ class GroongaHandlerTest < Test::Unit::TestCase end NORMALIZED_HEADER_SUCCESS = [ - Droonga::GroongaHandler::Status::SUCCESS, + Droonga::Plugins::Groonga::Status::SUCCESS, NORMALIZED_START_TIME, NORMALIZED_ELAPSED_TIME, ] NORMALIZED_HEADER_INVALID_ARGUMENT = [ - Droonga::GroongaHandler::Status::INVALID_ARGUMENT, + Droonga::Plugins::Groonga::Status::INVALID_ARGUMENT, NORMALIZED_START_TIME, NORMALIZED_ELAPSED_TIME, ] Renamed: test/unit/plugins/test_search.rb (+3 -3) 99% =================================================================== --- test/unit/plugin/handler/test_search.rb 2014-02-07 18:29:19 +0900 (abe3502) +++ test/unit/plugins/test_search.rb 2014-02-07 18:48:30 +0900 (b70b613) @@ -13,7 +13,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -require "droonga/plugin/handler/search" +require "droonga/plugins/search" class SearchHandlerTest < Test::Unit::TestCase def setup @@ -29,7 +29,7 @@ class SearchHandlerTest < Test::Unit::TestCase def setup_plugin @handler = Droonga::Test::StubHandler.new - @plugin = Droonga::SearchHandler.new(@handler) + @plugin = Droonga::Plugins::Search::Handler.new("droonga", @handler.context) @messenger = Droonga::Test::StubHandlerMessenger.new end @@ -41,7 +41,7 @@ class SearchHandlerTest < Test::Unit::TestCase private def search(request, headers={}) message = Droonga::Test::StubHandlerMessage.new(request, headers) - @plugin.search(message, @messenger) + @plugin.handle(message, @messenger) results_to_result_set(@messenger.values.first) end Renamed: test/unit/plugins/test_watch.rb (+16 -3) 90% =================================================================== --- test/unit/plugin/handler/test_watch.rb 2014-02-07 18:29:19 +0900 (0d26d2a) +++ test/unit/plugins/test_watch.rb 2014-02-07 18:48:30 +0900 (c943521) @@ -15,7 +15,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -require "droonga/plugin/handler/watch" +require "droonga/plugins/watch" class WatchHandlerTest < Test::Unit::TestCase include WatchHelper @@ -36,7 +36,6 @@ class WatchHandlerTest < Test::Unit::TestCase private def setup_plugin @handler = Droonga::Test::StubHandler.new - @plugin = Droonga::WatchHandler.new(@handler) @messenger = Droonga::Test::StubHandlerMessenger.new end @@ -46,11 +45,15 @@ class WatchHandlerTest < Test::Unit::TestCase def process(command, request, headers={}) message = Droonga::Test::StubHandlerMessage.new(request, headers) - @plugin.send(command, message, @messenger) + create_plugin.handle(message, @messenger) end public class SubscribeTest < self + def create_plugin + Droonga::Plugins::Watch::SubscribeHandler.new("droonga", @handler.context) + end + def test_subscribe request = { "route" => "localhost:23003/output", @@ -111,6 +114,11 @@ class WatchHandlerTest < Test::Unit::TestCase setup_subscription end + def create_plugin + Droonga::Plugins::Watch::UnsubscribeHandler.new("droonga", + @handler.context) + end + def test_unsubscribe request = { "route" => "localhost:23003/output", @@ -140,6 +148,11 @@ class WatchHandlerTest < Test::Unit::TestCase setup_subscription end + def create_plugin + Droonga::Plugins::Watch::FeedHandler.new("droonga", + @handler.context) + end + def test_feed_match request = { "targets" => {