[Groonga-commit] droonga/fluent-plugin-droonga at 3139fac [master] Move search procedures to searcher.rb.

Back to archive index

Daijiro MORI null+****@clear*****
Sat Aug 17 13:32:27 JST 2013


Daijiro MORI	2013-08-17 13:32:27 +0900 (Sat, 17 Aug 2013)

  New Revision: 3139faceea52772dd04bb1aa56f300a6f7bc2a34
  https://github.com/droonga/fluent-plugin-droonga/commit/3139faceea52772dd04bb1aa56f300a6f7bc2a34

  Message:
    Move search procedures to searcher.rb.

  Copied files:
    lib/droonga/searcher.rb
      (from lib/droonga/plugin/handler_search.rb)
  Modified files:
    lib/droonga/plugin/handler_proxy.rb
    lib/droonga/plugin/handler_search.rb

  Modified: lib/droonga/plugin/handler_proxy.rb (+3 -1)
===================================================================
--- lib/droonga/plugin/handler_proxy.rb    2013-08-17 01:04:54 +0900 (5685ab1)
+++ lib/droonga/plugin/handler_proxy.rb    2013-08-17 13:32:27 +0900 (1bbd93d)
@@ -16,6 +16,7 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 require "droonga/handler"
+require "droonga/searcher"
 
 module Droonga
   class BasicProxyHandler < Droonga::ProxyHandler
@@ -23,7 +24,8 @@ module Droonga
 
     command :proxy_search
     def proxy_search(request)
-      "dummy"
+      searcher = Droonga::Searcher.new(@context)
+      searcher.search(args)
     end
 
     command :proxy_gather

  Modified: lib/droonga/plugin/handler_search.rb (+3 -329)
===================================================================
--- lib/droonga/plugin/handler_search.rb    2013-08-17 01:04:54 +0900 (585313b)
+++ lib/droonga/plugin/handler_search.rb    2013-08-17 13:32:27 +0900 (1b773d0)
@@ -15,344 +15,18 @@
 # 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 "English"
-require "tsort"
-require "groonga"
-
 require "droonga/handler"
+require "droonga/searcher"
 
 module Droonga
   class SearchHandler < Droonga::Handler
     Droonga::HandlerPlugin.register("search", self)
 
-    class Error < StandardError
-    end
-
-    class UndefinedSourceError < Error
-      attr_reader :name
-      def initialize(name)
-        @name = name
-        super("undefined source was used: <#{name}>")
-      end
-    end
-
     command :search
     def search(request)
-      queries = request["queries"]
-      outputs = nil
-      @context.push_memory_pool do
-        outputs = process_queries(queries)
-      end
+      searcher = Droonga::Searcher.new(@context)
+      outputs = searcher.search(request["queries"])
       post(outputs)
     end
-
-    private
-    def process_queries(queries)
-      return {} unless queries
-      query_sorter = QuerySorter.new
-      queries.each do |name, query|
-        query_sorter.add(name, [query["source"]])
-      end
-      outputs = {}
-      results = {}
-      query_sorter.tsort.each do |name|
-        if queries[name]
-          searcher = QuerySearcher.new(@context, queries[name])
-          results[name] = searcher.search(results)
-          outputs[name] = searcher.format if searcher.need_output?
-        elsif @context[name]
-          results[name] = @context[name]
-        else
-          raise UndefinedSourceError.new(name)
-        end
-      end
-      return outputs
-    end
-
-    class QuerySorter
-      include TSort
-      def initialize()
-        @queries = {}
-      end
-
-      def add(name, sources=[])
-        @queries[name] = sources
-      end
-
-      def tsort_each_node(&block)
-        @queries.each_key(&block)
-      end
-
-      def tsort_each_child(node, &block)
-        if @queries[node]
-          @queries[node].each(&block)
-        end
-      end
-    end
-
-    class QuerySearcher
-      def initialize(context, query)
-        @context = context
-        @query = query
-        @result = nil
-        @condition = nil
-        @start_time = nil
-      end
-
-      def search(results)
-        search_query(results)
-      end
-
-      def need_output?
-        @result and****@query*****_key?("output")
-      end
-
-      def format
-        formatted_result = {}
-        format_count(formatted_result)
-        format_records(formatted_result)
-        if need_element_output?("startTime")
-          formatted_result["startTime"] = @start_time.iso8601
-        end
-        if need_element_output?("elapsedTime")
-          formatted_result["elapsedTime"] = Time.now.to_f - @start_time.to_f
-        end
-        formatted_result
-      end
-
-      private
-      def parseCondition(source, expression, condition)
-        if condition.is_a? String
-          expression.parse(condition, :syntax => :script)
-        elsif condition.is_a? Hash
-          options = {}
-          if condition["matchTo"]
-            matchTo = Groonga::Expression.new(context: @context)
-            matchTo.define_variable(:domain => source)
-            match_columns = condition["matchTo"]
-            match_columns = match_columns.join(",") if match_columns.is_a?(Array)
-            matchTo.parse(match_columns, :syntax => :script)
-            options[:default_column] = matchTo
-          end
-          if condition["query"]
-            options[:syntax] = :query
-            if condition["default_operator"]
-              case condition["default_operator"]
-              when "||"
-                options[:default_operator] = Groonga::Operator::OR
-              when "&&"
-                options[:default_operator] = Groonga::Operator::AND
-              when "-"
-                options[:default_operator] = Groonga::Operator::BUT
-              else
-                raise "undefined operator assigned #{condition["default_operator"]}"
-              end
-            end
-            if condition["allow_pragma"]
-              options[:allow_pragma] = true
-            end
-            if condition["allow_column"]
-              options[:allow_column] = true
-            end
-            expression.parse(condition["query"], options)
-          elsif condition["script"]
-            # "script" is ignored when "query" is also assigned.
-            options[:syntax] = :script
-            if condition["allow_update"]
-              options[:allow_update] = true
-            end
-            expression.parse(condition["script"], options)
-          else
-            raise "neither 'query' nor 'script' assigned in #{condition.inspect}"
-          end
-        elsif condition.is_a? Array
-          case condition[0]
-          when "||"
-            operator = Groonga::Operator::OR
-          when "&&"
-            operator = Groonga::Operator::AND
-          when "-"
-            operator = Groonga::Operator::BUT
-          else
-            raise "undefined operator assigned #{condition[0]}"
-          end
-          if condition[1]
-            parseCondition(source, expression, condition[1])
-          end
-          condition[2..-1].each do |element|
-            parseCondition(source, expression, element)
-            expression.append_operation(operator, 2)
-          end
-        else
-          raise "unacceptable object #{condition.inspect} assigned"
-        end
-      end
-
-      def parse_order_keys(keys)
-        keys.collect do |key|
-          if key =~ /^-/
-            [$POSTMATCH, :descending]
-          else
-            [key, :ascending]
-          end
-        end
-      end
-
-      def search_query(results)
-        @start_time = Time.now
-        @result = source = results[@query["source"]]
-        if @query["condition"]
-          expression = Groonga::Expression.new(context: @context)
-          expression.define_variable(:domain => source)
-          parseCondition(source, expression, @query["condition"])
-          @result = source.select(expression)
-          @condition = expression
-        end
-        if @query["groupBy"]
-          if @query["groupBy"].is_a? String
-            @result =****@resul*****(@query["groupBy"])
-          elsif @query["groupBy"].is_a? Hash
-            key = @query["groupBy"]["key"]
-            max_n_sub_records = @query["groupBy"]["maxNSubRecords"]
-            @result =****@resul*****(key, :max_n_sub_records => max_n_sub_records)
-          else
-            raise '"groupBy" parameter must be a Hash or a String'
-          end
-        end
-        @count =****@resul*****
-        if @query["sortBy"]
-          if @query["sortBy"].is_a? Array
-            keys = parse_order_keys(@query["sortBy"])
-            offset = 0
-            limit = -1
-          elsif @query["sortBy"].is_a? Hash
-            keys = parse_order_keys(@query["sortBy"]["keys"])
-            offset = @query["sortBy"]["offset"]
-            limit = @query["sortBy"]["limit"]
-          else
-            raise '"sortBy" parameter must be a Hash or an Array'
-          end
-          @result =****@resul*****(keys, :offset => offset, :limit => limit)
-        end
-        @result
-      end
-
-      def need_element_output?(element)
-        params = @query["output"]
-
-        elements = params["elements"]
-        return false if elements.nil?
-
-        elements.include?(element)
-      end
-
-      def format_count(formatted_result)
-        return unless need_element_output?("count")
-        formatted_result["count"] = @count
-      end
-
-      def format_records(formatted_result)
-        return unless need_element_output?("records")
-
-        params = @query["output"]
-
-        attributes = params["attributes"]
-        target_attributes = normalize_target_attributes(attributes)
-        offset = params["offset"] || 0
-        limit = params["limit"] || 10
-        @result.open_cursor(:offset => offset, :limit => limit) do |cursor|
-          if params["format"] == "complex"
-            formatted_result["records"] = cursor.collect do |record|
-              complex_record(target_attributes, record)
-            end
-          else
-            formatted_result["records"] = cursor.collect do |record|
-              simple_record(target_attributes, record)
-            end
-          end
-        end
-      end
-
-      def complex_record(attributes, record)
-        values = {}
-        attributes.collect do |attribute|
-          values[attribute[:label]] = record_value(record, attribute)
-        end
-        values
-      end
-
-      def simple_record(attributes, record)
-        attributes.collect do |attribute|
-          record_value(record, attribute)
-        end
-      end
-
-      def record_value(record, attribute)
-        if attribute[:source] == "_subrecs"
-          if @query["output"]["format"] == "complex"
-            record.sub_records.collect do |sub_record|
-              target_attributes = resolve_attributes(attribute, sub_record)
-              complex_record(target_attributes, sub_record)
-            end
-          else
-            record.sub_records.collect do |sub_record|
-              target_attributes = resolve_attributes(attribute, sub_record)
-              simple_record(target_attributes, sub_record)
-            end
-          end
-        else
-          expression = attribute[:expression]
-          if expression
-            variable = attribute[:variable]
-            variable.value = record
-            expression.execute
-          else
-            record[attribute[:source]]
-          end
-        end
-      end
-
-      def resolve_attributes(attribute, record)
-        unless attribute[:target_attributes]
-          attribute[:target_attributes] =
-            normalize_target_attributes(attribute[:attributes], record.table)
-        end
-        return attribute[:target_attributes]
-      end
-
-      def accessor_name?(source)
-        /\A[a-zA-Z\#@$_][a-zA-Z\d\#@$_\-.]*\z/ === source
-      end
-
-      def normalize_target_attributes(attributes, domain = @result)
-        attributes.collect do |attribute|
-          if attribute.is_a?(String)
-            attribute = {
-              "source" => attribute,
-            }
-          end
-          source = attribute["source"]
-          if accessor_name?(source)
-            expression = nil
-            variable = nil
-          else
-            expression = Groonga::Expression.new(context: @context)
-            variable = expression.define_variable(domain: domain)
-            expression.parse(source, syntax: :script)
-            condition = expression.define_variable(name: "$condition",
-                                                   reference: true)
-            condition.value = @condition
-            source = nil
-          end
-          {
-            label: attribute["label"] || attribute["source"],
-            source: source,
-            expression: expression,
-            variable: variable,
-            attributes: attribute["attributes"]
-          }
-        end
-      end
-    end
   end
 end

  Copied: lib/droonga/searcher.rb (+7 -9) 98%
===================================================================
--- lib/droonga/plugin/handler_search.rb    2013-08-17 01:04:54 +0900 (585313b)
+++ lib/droonga/searcher.rb    2013-08-17 13:32:27 +0900 (c1fd5fc)
@@ -19,12 +19,8 @@ require "English"
 require "tsort"
 require "groonga"
 
-require "droonga/handler"
-
 module Droonga
-  class SearchHandler < Droonga::Handler
-    Droonga::HandlerPlugin.register("search", self)
-
+  class Searcher
     class Error < StandardError
     end
 
@@ -36,14 +32,16 @@ module Droonga
       end
     end
 
-    command :search
-    def search(request)
-      queries = request["queries"]
+    def initialize(context)
+      @context = context
+    end
+
+    def search(queries)
       outputs = nil
       @context.push_memory_pool do
         outputs = process_queries(queries)
       end
-      post(outputs)
+      return outputs
     end
 
     private
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index