Kouhei Sutou
null+****@clear*****
Wed Dec 21 11:01:27 JST 2016
Kouhei Sutou 2016-12-21 11:01:27 +0900 (Wed, 21 Dec 2016) New Revision: 07056e3f1901af6ccc055cc64bd9cdbb89ba9397 https://github.com/ranguba/groonga-client/commit/07056e3f1901af6ccc055cc64bd9cdbb89ba9397 Message: select request: support filter(name, value) usage Copied files: test/request/select/test-filter-equal-parameter.rb (from test/request/select/test-filter-parameter.rb) Modified files: lib/groonga/client/request/select.rb Renamed files: test/request/select/test-filter-expression-parameter.rb (from test/request/select/test-filter-parameter.rb) Modified: lib/groonga/client/request/select.rb (+94 -33) =================================================================== --- lib/groonga/client/request/select.rb 2016-12-20 17:35:35 +0900 (e308e88) +++ lib/groonga/client/request/select.rb 2016-12-21 11:01:27 +0900 (2de851d) @@ -46,9 +46,49 @@ module Groonga RequestParameter.new(:query, value)) end - def filter(expression, values=nil) - add_parameter(FilterMerger, - FilterParameter.new(expression, values)) + # Adds a script syntax condition. If the request already has + # any filter condition, they are combined by AND. + # + # @example: Multiple filters + # request. + # filter("user", "alice"). + # # -> --filter 'user == "alice"' + # filter("tags @ %{tag}", tag: "Ruby") + # # -> --filter '(user == "alice") && (tags @ "Ruby")' + # + # @return [Groonga::Client::Request::Select] + # The new request with the given condition. + # + # @overload filter(column_name, value) + # @param [String, Symbol] column_name The target column name. + # @param [Object] value The column value. It's escaped automatically. + # + # Adds a `#{column_name} == #{value}` condition. + # + # @overload filter(expression, values=nil) + # @param [String] expression The script syntax expression. + # It can includes `%{name}`s as placeholder. They are expanded + # by `String#%` with the given `values` argument. + # @param [nil, ::Hash] values The values to be expanded. + # If the given `expression` doesn't have placeholder, you + # should specify `nil`. + # + # Values are escaped automatically. Values passed from + # external should be escaped. + # + # Adds a `#{expression % values}` condition. + def filter(expression_or_column_name, values_or_value=nil) + if expression_or_column_name.is_a?(Symbol) + parameter = FilterEqualParameter.new(expression_or_column_name, + values_or_value) + elsif values_or_value.nil? or values_or_value.is_a?(::Hash) + parameter = FilterExpressionParameter.new(expression_or_column_name, + values_or_value) + else + parameter = FilterEqualParameter.new(expression_or_column_name, + values_or_value) + end + add_parameter(FilterMerger, parameter) end def output_columns(value) @@ -190,36 +230,7 @@ module Groonga end # @private - class FilterParameter - def initialize(expression, values) - @expression = expression - @values = values - end - - def to_parameters - case @expression - when String - return {} if /\A\s*\z/ === @expression - expression = @expression - when NilClass - return {} - else - expression = @expression - end - - if****@value*****_a?(::Hash) and not****@value*****? - escaped_values = {} - @values.each do |key, value| - escaped_values[key] = escape_filter_value(value) - end - expression = expression % escaped_values - end - - { - filter: expression, - } - end - + module FilterValueEscapable private def escape_filter_value(value) case value @@ -258,6 +269,56 @@ module Groonga end # @private + class FilterExpressionParameter + include FilterValueEscapable + + def initialize(expression, values) + @expression = expression + @values = values + end + + def to_parameters + case @expression + when String + return {} if /\A\s*\z/ === @expression + expression = @expression + when NilClass + return {} + else + expression = @expression + end + + if****@value*****_a?(::Hash) and not****@value*****? + 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 + class FilterEqualParameter + include FilterValueEscapable + + def initialize(column_name, value) + @column_name = column_name + @value = value + end + + def to_parameters + { + filter: "#{@column_name} == #{escape_filter_value(@value)}", + } + end + end + + # @private class OutputColumnsParameter < ValuesParameter def initialize(prefix, output_columns) super([:"#{prefix}output_columns"], output_columns) Copied: test/request/select/test-filter-equal-parameter.rb (+21 -36) 53% =================================================================== --- test/request/select/test-filter-parameter.rb 2016-12-20 17:35:35 +0900 (7e76631) +++ test/request/select/test-filter-equal-parameter.rb 2016-12-21 11:01:27 +0900 (0594e87) @@ -14,35 +14,33 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -class TestRequestSelectFilterParmater < Test::Unit::TestCase - def filter_parameter(expression, values=nil) - Groonga::Client::Request::Select::FilterParameter.new(expression, values) +class TestRequestSelectFilterEqualParmater < Test::Unit::TestCase + def filter_parameter(column_name, value) + Groonga::Client::Request::Select::FilterEqualParameter.new(column_name, + value) end - def to_parameters(expression, values=nil) - filter_parameter(expression, values).to_parameters + def to_parameters(column_name, value) + filter_parameter(column_name, value).to_parameters end - sub_test_case("expression") do - def test_nil - assert_equal({}, - to_parameters(nil)) - end - + sub_test_case("column name") do def test_string assert_equal({ - :filter => "age <= 20", + :filter => "_key == 29", }, - to_parameters("age <= 20")) + to_parameters("_key", 29)) end - def test_empty_string - assert_equal({}, - to_parameters("")) + def test_symbol + assert_equal({ + :filter => "_key == 29", + }, + to_parameters(:_key, 29)) end end - sub_test_case("values") do + sub_test_case("value") do def test_string filter = <<-'FILTER'.strip title == "[\"He\\ llo\"]" @@ -50,48 +48,35 @@ title == "[\"He\\ llo\"]" assert_equal({ :filter => filter, }, - to_parameters("title == %{value}", - :value => "[\"He\\ llo\"]")) + to_parameters("title", "[\"He\\ llo\"]")) end def test_symbol assert_equal({ :filter => "title == \"Hello\"", }, - to_parameters("title == %{value}", - :value => :Hello)) + to_parameters("title", :Hello)) end def test_number assert_equal({ - :filter => "age <= 29", + :filter => "age == 29", }, - to_parameters("age <= %{value}", - :value => 29)) + to_parameters("age", 29)) end def test_true assert_equal({ :filter => "published == true", }, - to_parameters("published == %{value}", - :value => true)) + to_parameters("published", 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)) + to_parameters("published", false)) end end end Renamed: test/request/select/test-filter-expression-parameter.rb (+3 -2) 92% =================================================================== --- test/request/select/test-filter-parameter.rb 2016-12-20 17:35:35 +0900 (7e76631) +++ test/request/select/test-filter-expression-parameter.rb 2016-12-21 11:01:27 +0900 (dc9f3a6) @@ -14,9 +14,10 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -class TestRequestSelectFilterParmater < Test::Unit::TestCase +class TestRequestSelectFilterExpressionParmater < Test::Unit::TestCase def filter_parameter(expression, values=nil) - Groonga::Client::Request::Select::FilterParameter.new(expression, values) + Groonga::Client::Request::Select::FilterExpressionParameter.new(expression, + values) end def to_parameters(expression, values=nil) -------------- next part -------------- HTML����������������������������...Download