Skip to content

Commit

Permalink
Adds support for per = 0
Browse files Browse the repository at this point in the history
When running a Scope with `per: 0` only the count query will
be executed.
  • Loading branch information
radiospiel committed May 3, 2018
1 parent 1ebbf6a commit 77dc3d8
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 4 deletions.
7 changes: 5 additions & 2 deletions lib/simple/sql/connection_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,9 @@ def ask(sql, *args, into: nil)

def add_page_info(scope, results)
raise ArgumentError, "expect Array but get a #{results.class.name}" unless results.is_a?(Array)
raise ArgumentError, "per must be > 0" unless scope.per > 0

# optimization: add empty case (page <= 1 && results.empty?)
if scope.page <= 1 && results.empty?
if scope.page <= 1 && scope.per > 0 && results.empty?
Scope::PageInfo.attach(results, total_count: 0, per: scope.per, page: 1)
else
sql = "SELECT COUNT(*) FROM (#{scope.order_by(nil).to_sql(pagination: false)}) simple_sql_count"
Expand All @@ -80,6 +79,8 @@ def exec_logged(sql_or_scope, *args)
if sql_or_scope.is_a?(Scope)
raise ArgumentError, "You cannot call .all with a scope and additional arguments" unless args.empty?

return [] if sql_or_scope.per == 0

sql = sql_or_scope.to_sql
args = sql_or_scope.args
else
Expand All @@ -92,6 +93,8 @@ def exec_logged(sql_or_scope, *args)
end

def enumerate(result, into:, &block)
return result if result.is_a?(Array) && result.empty?

decoder = Decoder.new(self, result, into: into)

if block
Expand Down
4 changes: 2 additions & 2 deletions lib/simple/sql/scope.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def where(sql_fragment, arg = :__dummy__no__arg, placeholder: "?")
end

# Set pagination
def paginate(per:, page:)
def paginate(per:, page: 1)
duplicate.send(:paginate!, per: per, page: page)
end

Expand Down Expand Up @@ -126,7 +126,7 @@ module PageInfo
def self.attach(results, total_count:, per:, page:)
results.extend(self)
results.instance_variable_set :@total_count, total_count
results.instance_variable_set :@total_pages, (total_count + (per - 1)) / per
results.instance_variable_set :@total_pages, per > 0 ? (total_count + (per - 1)) / per : -1
results.instance_variable_set :@current_page, page
results
end
Expand Down
12 changes: 12 additions & 0 deletions spec/simple/sql_scope_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,18 @@ def expects(expected_result, sql, *args)
end
end

context "with per=0" do
let(:result) { SQL.all(scope.paginate(per: 0)) }

it "returns an empty result set" do
expect(result).to eq([])
end

it "adds total_count info to the .all return value" do
expect(result.total_count).to eq(2)
end
end

context "with per=2" do
it "returns an empty array after the last page" do
result = SQL.all(scope.paginate(per: 2, page: 2))
Expand Down

0 comments on commit 77dc3d8

Please sign in to comment.