Skip to content

Commit

Permalink
Merge pull request #49 from haslo/offset_for_resultset
Browse files Browse the repository at this point in the history
Added offset option for Resultset
  • Loading branch information
gernotkogler committed Dec 4, 2015
2 parents acfba8e + 1e698b0 commit d7dbe9a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 8 deletions.
20 changes: 14 additions & 6 deletions lib/xapian_db/resultset.rb
Expand Up @@ -46,6 +46,7 @@ class Resultset < Array
# @param [Hash] options
# @option options [Integer] :db_size The current size (nr of docs) of the database
# @option options [Integer] :limit The maximum number of documents to retrieve
# @option options [Integer] :offset The index of the first result to retrieve
# @option options [Integer] :page (1) The page number to retrieve
# @option options [Integer] :per_page (10) How many docs per page? Ignored if a limit option is given
# @option options [String] :spelling_suggestion (nil) The spelling corrected query (if a language is configured)
Expand All @@ -56,25 +57,32 @@ def initialize(enquiry, options={})
db_size = params.delete :db_size
@spelling_suggestion = params.delete :spelling_suggestion
limit = params.delete :limit
offset = params.delete :offset
page = params.delete :page
per_page = params.delete :per_page
raise ArgumentError.new "unsupported options for resultset: #{params}" if params.size > 0
raise ArgumentError.new "db_size option is required" unless db_size

unless (page.nil? && per_page.nil?) || (limit.nil? && offset.nil?)
raise ArgumentError.new "Impossible combination of parameters. Either pass page and/or per_page, or limit and/or offset."
end

calculated_page = offset.nil? || limit.nil? ? nil : (offset.to_f / limit.to_f) + 1

limit = limit.nil? ? db_size : limit.to_i
per_page = per_page.nil? ? limit : per_page.to_i
page = page.nil? ? 1 : page.to_i
offset = (page - 1) * per_page
count = offset + per_page < limit ? per_page : limit - offset
per_page = per_page.nil? ? limit.to_i : per_page.to_i
page = page.nil? ? (calculated_page.nil? ? 1 : calculated_page) : page.to_i
offset = offset.nil? ? (page - 1) * per_page : offset.to_i
count = per_page < limit ? per_page : limit

return build_empty_resultset if (page - 1) * per_page > db_size
result_window = enquiry.mset(offset, count)
@hits = result_window.matches_estimated
return build_empty_resultset if @hits == 0
raise ArgumentError.new "page #{@page} does not exist" if @hits > 0 && offset >= limit

self.replace result_window.matches.map{|match| decorate(match).document}
@total_pages = (@hits / per_page.to_f).ceil
@current_page = page
@current_page = (page == page.to_i) ? page.to_i : page
@limit_value = per_page
end

Expand Down
21 changes: 19 additions & 2 deletions spec/xapian_db/resultset_spec.rb
Expand Up @@ -75,6 +75,18 @@
expect(resultset.size).to eq(2)
expect(resultset.current_page).to eq(1)
expect(resultset.total_pages).to eq(2)
expect(resultset.limit_value).to eq(2)
expect(resultset.total_count).to eq(@matches.size)
expect(resultset.total_entries).to eq(@matches.size)
end

it "accepts an offset option (as a string or an integer)" do
allow(@mset).to receive(:matches).and_return(@matches[1..2])
resultset = XapianDb::Resultset.new(@enquiry, :db_size => @matches.size, :limit => "2", offset: "1")
expect(resultset.hits).to eq(3)
expect(resultset.size).to eq(2)
expect(resultset.current_page).to eq(1.5)
expect(resultset.total_pages).to eq(2)
expect(resultset.total_count).to eq(@matches.size)
expect(resultset.total_entries).to eq(@matches.size)
end
Expand Down Expand Up @@ -109,8 +121,13 @@
expect(resultset.total_pages).to eq(2)
end

it "raises an exception if page is requested that does not exist" do
expect{XapianDb::Resultset.new(@enquiry, :db_size => @matches.size, :per_page => 2, :page => 3)}.to raise_error "page does not exist"
it "returns an empty result set if page is requested that does not exist" do
expect(XapianDb::Resultset.new(@enquiry, db_size: @matches.size, per_page: 2, :page => 3).count).to eq(0)
end

it "raises an exception if elements of both page / per_page and offset / limit are given" do
expected_error = "Impossible combination of parameters. Either pass page and/or per_page, or limit and/or offset."
expect{XapianDb::Resultset.new(@enquiry, db_size: @matches.size, per_page: 2, page: 2, offset: 1, limit: 2)}.to raise_error ArgumentError, expected_error
end

it "should populate itself with found xapian documents" do
Expand Down

0 comments on commit d7dbe9a

Please sign in to comment.