[Groonga-commit] ranguba/groonga-client-rails at c54c6e6 [master] Support filter

Back to archive index

Kouhei Sutou null+****@clear*****
Sun Mar 27 22:19:42 JST 2016


Kouhei Sutou	2016-03-27 22:19:42 +0900 (Sun, 27 Mar 2016)

  New Revision: c54c6e6dda1294ad95631144c36c424b32d54d74
  https://github.com/ranguba/groonga-client-rails/commit/c54c6e6dda1294ad95631144c36c424b32d54d74

  Message:
    Support filter

  Added files:
    test/unit/searcher/select/filter_parameter_test.rb
  Modified files:
    lib/groonga/client/searcher.rb
    lib/groonga/client/searcher/select/request.rb
    test/apps/rails4-mongoid/test/searchers/posts_searcher_test.rb

  Modified: lib/groonga/client/searcher.rb (+2 -0)
===================================================================
--- lib/groonga/client/searcher.rb    2016-03-27 22:16:14 +0900 (470e5fd)
+++ lib/groonga/client/searcher.rb    2016-03-27 22:19:42 +0900 (641c60b)
@@ -14,6 +14,8 @@
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
+require "groonga/client"
+
 require "groonga/client/searcher/select"
 require "groonga/client/searcher/schema"
 require "groonga/client/searcher/schema_synchronizer"

  Modified: lib/groonga/client/searcher/select/request.rb (+85 -0)
===================================================================
--- lib/groonga/client/searcher/select/request.rb    2016-03-27 22:16:14 +0900 (9f9f6ad)
+++ lib/groonga/client/searcher/select/request.rb    2016-03-27 22:19:42 +0900 (bae2088)
@@ -47,6 +47,11 @@ module Groonga
                           RequestParameter.new(:query, value))
           end
 
+          def filter(expression, values=nil)
+            add_parameter(FilterMerger,
+                          FilterParameter.new(expression, values))
+          end
+
           def output_columns(value)
             add_parameter(OverwriteMerger,
                           OutputColumnsParameter.new(value))
@@ -76,6 +81,23 @@ module Groonga
         end
 
         # @private
+        class FilterMerger < ParameterMerger
+          def to_parameters
+            params1 =****@param*****_parameters
+            params2 =****@param*****_parameters
+            params = params1.merge(params2)
+            filter1 = params1[:filter]
+            filter2 = params2[:filter]
+            if filter1.present? and filter2.present?
+              params[:filter] = "(#{filter1}) && (#{filter2})"
+            else
+              params[:filter] = (filter1 || filter2)
+            end
+            params
+          end
+        end
+
+        # @private
         class MatchColumnsParameter
           def initialize(match_columns)
             @match_columns = match_columns
@@ -101,6 +123,69 @@ module Groonga
         end
 
         # @private
+        class FilterParameter
+          def initialize(expression, values)
+            @expression = expression
+            @values = values
+          end
+
+          def to_parameters
+            if****@expre*****?
+              {}
+            else
+              if****@value*****?
+                expression = @expression
+              else
+                escaped_values = {}
+                @values.each do |key, value|
+                  escaped_values[key] = escape_filter_value(value)
+                end
+                expression = @expression % escaped_values
+              end
+              {
+                filter: expression,
+              }
+            end
+          end
+
+          private
+          def escape_filter_value(value)
+            case value
+            when Numeric
+              value
+            when TrueClass, FalseClass
+              value
+            when NilClass
+              "null"
+            when String
+              ScriptSyntax.format_string(value)
+            when Symbol
+              ScriptSyntax.format_string(value.to_s)
+            when ::Array
+              escaped_value = "["
+              value.each_with_index do |element, i|
+                escaped_value << ", " if i > 0
+                escaped_value << escape_filter_value(element)
+              end
+              escaped_value << "]"
+              escaped_value
+            when ::Hash
+              escaped_value = "{"
+              value.each_with_index do |(k, v), i|
+                escaped_value << ", " if i > 0
+                escaped_value << escape_filter_value(k.to_s)
+                escaped_value << ": "
+                escaped_value << escape_filter_value(v)
+              end
+              escaped_value << "}"
+              escaped_value
+            else
+              value
+            end
+          end
+        end
+
+        # @private
         class OutputColumnsParameter
           def initialize(output_columns)
             @output_columns = output_columns

  Modified: test/apps/rails4-mongoid/test/searchers/posts_searcher_test.rb (+35 -0)
===================================================================
--- test/apps/rails4-mongoid/test/searchers/posts_searcher_test.rb    2016-03-27 22:16:14 +0900 (98d3330)
+++ test/apps/rails4-mongoid/test/searchers/posts_searcher_test.rb    2016-03-27 22:19:42 +0900 (ec16e66)
@@ -22,6 +22,41 @@ class PostsSearcherTest < ActionController::TestCase
                  result_set.records.collect {|record| record["body"]})
   end
 
+  test "should be searchable by a filter" do
+    create(:post, body: "Hello World")
+    create(:post, body: "Hello Rails")
+    result_set = @searcher.
+      search.
+      filter("body @ %{keyword}", {keyword: "World"}).
+      result_set
+    assert_equal(["Hello World"],
+                 result_set.records.collect {|record| record["body"]})
+  end
+
+  test "should be searchable by filters" do
+    create(:post, body: "Hello World")
+    create(:post, body: "Hello Rails")
+    create(:post, body: "Hi World")
+    result_set = @searcher.
+      search.
+      filter("body @ %{keyword}", {keyword: "Hello"}).
+      filter("body @ %{keyword}", {keyword: "World"}).
+      result_set
+    assert_equal(["Hello World"],
+                 result_set.records.collect {|record| record["body"]})
+  end
+
+  test "should be searchable with special characters by a filter" do
+    create(:post, body: "Hello \"Wo\\rld\"")
+    create(:post, body: "Hello Rails")
+    result_set = @searcher.
+      search.
+      filter("body @ %{keyword}", {keyword: "\"Wo\\rld\""}).
+      result_set
+    assert_equal(["Hello \"Wo\\rld\""],
+                 result_set.records.collect {|record| record["body"]})
+  end
+
   test "should support snippet_html in output_columns" do
     create(:post, body: "Hello World")
     create(:post, body: "Hi Rails! Hello!")

  Added: test/unit/searcher/select/filter_parameter_test.rb (+99 -0) 100644
===================================================================
--- /dev/null
+++ test/unit/searcher/select/filter_parameter_test.rb    2016-03-27 22:19:42 +0900 (2559705)
@@ -0,0 +1,99 @@
+# Copyright (C) 2016  Kouhei Sutou <kou �� clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+require "test_helper"
+
+class SearcherSelectFilterParameterTest < Test::Unit::TestCase
+  def filter_parameter(expression, values=nil)
+    Groonga::Client::Searcher::Select::FilterParameter.new(expression, values)
+  end
+
+  def to_parameters(expression, values=nil)
+    filter_parameter(expression, values).to_parameters
+  end
+
+  sub_test_case("expression") do
+    def test_nil
+      assert_equal({},
+                   to_parameters(nil))
+    end
+
+    def test_string
+      assert_equal({
+                     :filter => "age <= 20",
+                   },
+                   to_parameters("age <= 20"))
+    end
+
+    def test_empty_string
+      assert_equal({},
+                   to_parameters(""))
+    end
+  end
+
+  sub_test_case("values") do
+    def test_string
+      filter = <<-'FILTER'.strip
+title == "[\"He\\ llo\"]"
+      FILTER
+      assert_equal({
+                     :filter => filter,
+                   },
+                   to_parameters("title == %{value}",
+                                 :value => "[\"He\\ llo\"]"))
+    end
+
+    def test_symbol
+      assert_equal({
+                     :filter => "title == \"Hello\"",
+                   },
+                   to_parameters("title == %{value}",
+                                 :value => :Hello))
+    end
+
+    def test_number
+      assert_equal({
+                     :filter => "age <= 29",
+                   },
+                   to_parameters("age <= %{value}",
+                                 :value => 29))
+    end
+
+    def test_true
+      assert_equal({
+                     :filter => "published == true",
+                   },
+                   to_parameters("published == %{value}",
+                                 :value => true))
+    end
+
+    def test_false
+      assert_equal({
+                     :filter => "published == false",
+                   },
+                   to_parameters("published == %{value}",
+                                 :value => false))
+    end
+
+    def test_nil
+      assert_equal({
+                     :filter => "function(null)",
+                   },
+                   to_parameters("function(%{value})",
+                                 :value => nil))
+    end
+  end
+end
-------------- next part --------------
HTML����������������������������...
Descargar 



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