Kouhei Sutou
null+****@clear*****
Mon May 30 12:13:54 JST 2016
Kouhei Sutou 2016-05-30 12:13:54 +0900 (Mon, 30 May 2016) New Revision: bbcdd324787e3f4199c7d2a22e1efd26ff4a91c7 https://github.com/ranguba/groonga-client/commit/bbcdd324787e3f4199c7d2a22e1efd26ff4a91c7 Message: select: support command version 3 Added files: test/response/test-select-command-version3.rb Modified files: lib/groonga/client/response/base.rb lib/groonga/client/response/select.rb test/response/test-select-command-version1.rb Modified: lib/groonga/client/response/base.rb (+5 -1) =================================================================== --- lib/groonga/client/response/base.rb 2016-05-30 10:56:29 +0900 (5226446) +++ lib/groonga/client/response/base.rb 2016-05-30 12:13:54 +0900 (3d2722b) @@ -61,22 +61,26 @@ module Groonga class Base class << self def parse(command, raw_response) + return_code = nil case command.output_type when :json response = JSON.parse(raw_response) if response.is_a?(::Array) header, body = response + return_code = header[0] if header else header = response["header"] body = response["body"] + return_code = header["return_code"] if header end when :xml header, body = parse_xml(raw_response) + return_code = header[0] if header else header = nil body = raw_response end - if header.nil? or header[0].zero? + if header.nil? or return_code == 0 response = new(command, header, body) else response = Error.new(command, header, body) Modified: lib/groonga/client/response/select.rb (+51 -23) =================================================================== --- lib/groonga/client/response/select.rb 2016-05-30 10:56:29 +0900 (61ae899) +++ lib/groonga/client/response/select.rb 2016-05-30 12:13:54 +0900 (27d7a65) @@ -36,33 +36,42 @@ module Groonga private def parse_body(body) - @n_hits, @records = parse_match_records(body.first) - @drilldowns = parse_drilldowns(body[1..-1]) + if body.is_a?(::Array) + @n_hits, @records = parse_match_records_v1(body.first) + @drilldowns = parse_drilldowns_v1(body[1..-1]) + else + @n_hits, @records = parse_match_records_v3(body) + @drilldowns = parse_drilldowns_v3(body["drilldowns"]) + end body end - def parse_result(raw_result) - n_hits = raw_result.first.first + def parse_records(raw_columns, raw_records) column_names = {} - properties = raw_result[1].collect do |column_name, column_type| - base_column_name = column_name + columns = raw_columns.collect do |column| + if column.is_a?(::Array) + name, type = column + else + name = column["name"] + type = column["type"] + end + base_column_name = name suffix = 2 - while column_names.key?(column_name) - column_name = "#{base_column_name}#{suffix}" + while column_names.key?(name) + name = "#{base_column_name}#{suffix}" suffix += 1 end - column_names[column_name] = true - [column_name, column_type] + column_names[name] = true + [name, type] end - infos = raw_result[2..-1] || [] - items = infos.collect do |info| - item = {} - properties.each_with_index do |(name, type), i| - item[name] = convert_value(info[i], type) + + (raw_records || []).collect do |raw_record| + record = {} + columns.each_with_index do |(name, type), i| + record[name] = convert_value(raw_record[i], type) end - item + record end - [n_hits, items] end def convert_value(value, type) @@ -74,19 +83,38 @@ module Groonga end end - def parse_match_records(raw_records) - parse_result(raw_records) + def parse_match_records_v1(raw_records) + [ + raw_records.first.first, + parse_records(raw_records[1], raw_records[2..-1]), + ] end - def parse_drilldowns(raw_drilldowns) + def parse_match_records_v3(raw_records) + [ + raw_records["n_hits"], + parse_records(raw_records["columns"], raw_records["records"]), + ] + end + + def parse_drilldowns_v1(raw_drilldowns) (raw_drilldowns || []).collect.with_index do |raw_drilldown, i| key =****@comma*****[i] - n_hits, items = parse_result(raw_drilldown) - Drilldown.new(key, n_hits, items) + n_hits, records = parse_match_records_v1(raw_drilldown) + Drilldown.new(key, n_hits, records) + end + end + + def parse_drilldowns_v3(raw_drilldowns) + (raw_drilldowns || {}).collect do |(key, raw_drilldown)| + n_hits, records = parse_match_records_v3(raw_drilldown) + Drilldown.new(key, n_hits, records) end end - class Drilldown < Struct.new(:key, :n_hits, :items) + class Drilldown < Struct.new(:key, :n_hits, :records) + # @deprecated since 0.2.6. Use {#records} instead. + alias_method :items, :records end end end Modified: test/response/test-select-command-version1.rb (+2 -2) =================================================================== --- test/response/test-select-command-version1.rb 2016-05-30 10:56:29 +0900 (710abd5) +++ test/response/test-select-command-version1.rb 2016-05-30 12:13:54 +0900 (b08c66c) @@ -88,7 +88,7 @@ class TestResponseSelectCommandVersion1 < Test::Unit::TestCase class TestDrilldowns < self def setup pair_arguments = { - "drilldown" => "_key", + "drilldown" => "tag", "drilldown_output_columns" => "_key,_nsubrecs", } @command = Groonga::Command::Select.new("select", pair_arguments) @@ -108,7 +108,7 @@ class TestResponseSelectCommandVersion1 < Test::Unit::TestCase ["rroonga", 9], ], ] - assert_equal(["_key"], + assert_equal(["tag"], drilldowns(body).collect(&:key)) end Added: test/response/test-select-command-version3.rb (+247 -0) 100644 =================================================================== --- /dev/null +++ test/response/test-select-command-version3.rb 2016-05-30 12:13:54 +0900 (56ab249) @@ -0,0 +1,247 @@ +# Copyright (C) 2013-2016 Kouhei Sutou <kou �� clear-code.com> +# Copyright (C) 2013 Kosuke Asami +# +# 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 "response/helper" + +class TestResponseSelectCommandVersion3 < Test::Unit::TestCase + class TestParseRawResponse < self + include TestResponseHelper + + def test_select + header = { + "return_code" => 0, + "start_time" => 1372430096.70991, + "elapsed_time" => 0.000522851943969727, + } + body = { + "n_hits" => 1, + "columns" => [ + { + "name" => "_id", + "type" => "UInt32", + }, + ], + "records" => [ + 1, + ], + } + raw_response = { + "header" => header, + "body" => body, + }.to_json + + response = parse_raw_response("select", raw_response) + assert_equal(Groonga::Client::Response::Select, response.class) + end + end + + class TestBody < self + def setup + @command = Groonga::Command::Select.new("select", {}) + end + + def test_n_hits + response = create_response({ + "n_hits" => 29, + "columns" => [ + { + "name" => "_id", + "type" => "UInt32", + }, + ], + "records" => [ + ], + }) + assert_equal(29, response.n_hits) + end + + private + def create_response(body) + header = { + "return_code" => 0, + "start_time" => 1372430096.70991, + "elapsed_time" => 0.000522851943969727, + } + Groonga::Client::Response::Select.new(@command, header, body) + end + + class TestRecords < self + def test_time + updated_at = 1379040474 + assert_equal([{"updated_at" => Time.at(updated_at)}], + records({ + "n_hits" => 1, + "columns" => [ + { + "name" => "updated_at", + "type" => "Time", + }, + ], + "records" => [ + [updated_at], + ], + })) + end + + def test_duplicated_column_name + assert_equal([ + { + "html_escape" => "content1", + "html_escape2" => "content2", + "html_escape3" => "content3", + } + ], + records({ + "n_hits" => 1, + "columns" => [ + { + "name" => "html_escape", + "type" => nil, + }, + { + "name" => "html_escape", + "type" => nil, + }, + { + "name" => "html_escape", + "type" => nil, + } + ], + "records" => [ + ["content1", "content2", "content3"], + ], + })) + end + + private + def records(body) + create_response(body).records + end + end + + class TestDrilldowns < self + def setup + pair_arguments = { + "drilldown" => "tag", + "drilldown_output_columns" => "_key,_nsubrecs", + } + @command = Groonga::Command::Select.new("select", pair_arguments) + end + + def test_key + body = { + "n_hits" => 0, + "columns" => [], + "records" => [], + "drilldowns" => { + "tag" => { + "n_hits" => 29, + "columns" => [ + { + "name" => "_key", + "type" => "ShortText", + }, + { + "name" => "_nsubrecs", + "type" => "Int32", + }, + ], + "records" => [ + ["groonga", 29], + ["Ruby", 19], + ["rroonga", 9], + ], + }, + }, + } + assert_equal(["tag"], + drilldowns(body).collect(&:key)) + end + + def test_n_hits + body = { + "n_hits" => 0, + "columns" => [], + "records" => [], + "drilldowns" => { + "tag" => { + "n_hits" => 29, + "columns" => [ + { + "name" => "_key", + "type" => "ShortText", + }, + { + "name" => "_nsubrecs", + "type" => "Int32", + }, + ], + "records" => [ + ["groonga", 29], + ["Ruby", 19], + ["rroonga", 9], + ], + }, + }, + } + assert_equal([29], + drilldowns(body).collect(&:n_hits)) + end + + def test_items + body = { + "n_hits" => 0, + "columns" => [], + "records" => [], + "drilldowns" => { + "tag" => { + "n_hits" => 29, + "columns" => [ + { + "name" => "_key", + "type" => "ShortText", + }, + { + "name" => "_nsubrecs", + "type" => "Int32", + }, + ], + "records" => [ + ["groonga", 29], + ["Ruby", 19], + ["rroonga", 9], + ], + }, + }, + } + assert_equal([ + [ + {"_key" => "groonga", "_nsubrecs" => 29}, + {"_key" => "Ruby", "_nsubrecs" => 19}, + {"_key" => "rroonga", "_nsubrecs" => 9}, + ], + ], + drilldowns(body).collect(&:items)) + end + + private + def drilldowns(body) + create_response(body).drilldowns + end + end + end +end -------------- next part -------------- HTML����������������������������... 下載