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