def run
response = Response.new request(:search, @queue)
results = @queue.collect do
result = {
:matches => [],
:fields => [],
:attributes => {},
:attribute_names => [],
:words => {}
}
result[:status] = response.next_int
case result[:status]
when Statuses[:warning]
result[:warning] = response.next
when Statuses[:error]
result[:error] = response.next
next result
end
result[:fields] = response.next_array
attributes = response.next_int
attributes.times do
attribute_name = response.next
type = response.next_int
result[:attributes][attribute_name] = type
result[:attribute_names] << attribute_name
end
result_attribute_names_and_types = result[:attribute_names].
inject([]) { |array, attr| array.push([ attr, result[:attributes][attr] ]) }
matches = response.next_int
is_64_bit = response.next_int
result[:matches] = (0...matches).map do |i|
doc = is_64_bit > 0 ? response.next_64bit_int : response.next_int
weight = response.next_int
current_match_attributes = {}
result_attribute_names_and_types.each do |attr, type|
current_match_attributes[attr] = attribute_from_type(type, response)
end
{:doc => doc, :weight => weight, :index => i, :attributes => current_match_attributes}
end
result[:total] = response.next_int.to_i || 0
result[:total_found] = response.next_int.to_i || 0
result[:time] = ('%.3f' % (response.next_int / 1000.0)).to_f || 0.0
words = response.next_int
words.times do
word = response.next
docs = response.next_int
hits = response.next_int
result[:words][word] = {:docs => docs, :hits => hits}
end
result
end
@queue.clear
results
rescue Riddle::OutOfBoundsError => error
raise error
rescue => original
error = ResponseError.new original.message
error.original = original
raise error
end