1module Groonga
2  class Command
3    @@classes = {}
4    class << self
5      def register_class(name, klass)
6        @@classes[name] = klass
7      end
8
9      def find_class(name)
10        @@classes[name]
11      end
12    end
13
14    private
15    def context
16      @context ||= Context.instance
17    end
18
19    def writer
20      @writer ||= context.writer
21    end
22
23    def query_logger
24      @query_logger ||= context.query_logger
25    end
26
27    def cache_key(input)
28      nil
29    end
30
31    def cache_output(key, options={})
32      if key.nil?
33        yield
34      else
35        cache = Cache.current
36        cached_value = cache.fetch(key)
37        if cached_value
38          context.output = cached_value
39          query_logger.log(:cache, ":", "cache(#{cached_value.bytesize})")
40        else
41          yield
42          cache.update(key, context.output) if options[:update]
43        end
44      end
45    end
46
47    def run_internal(input)
48      begin
49        options = {
50          :update => (input["cache"] != "no"),
51        }
52        cache_output(cache_key(input), options) do
53          run_body(input)
54        end
55      rescue GroongaError => groonga_error
56        context.set_groonga_error(groonga_error)
57        nil
58      rescue => error
59        context.record_error(:command_error, error)
60        nil
61      end
62    end
63  end
64end
65