sequel-seek-pagination 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3c6ce6e2a2e78ab2b3741bc2037a2ef40bb85cc7
4
- data.tar.gz: 4d1dd2e3c9852312ba44ad35b389d45de5aca54a
3
+ metadata.gz: 9f9206a9a384b1cdf9e934dc6e414c7e31a7572b
4
+ data.tar.gz: e717fb468e5a8224e5c7cd48e1b40b91bffb318f
5
5
  SHA512:
6
- metadata.gz: c189067b2cc80490d41c684a891ec3486eaa0a675f599bfe3bcb066fceb5a698ce79fdc2aceb0e7f683f37e6a30e0af20f763ba82b3a883004fc53960dbca3a2
7
- data.tar.gz: 040bfa003540c47c7faa0367685c0d718bfe19955ce26fed037835a22ec3319e89da21e60123134830f540aef1f8693cc21dcec92f849af39c7a033f5fb70de4
6
+ metadata.gz: e358d7edefd328fa41a0378f52f25c4c3e05b98b0da49a74742241a2f487ef8eb383dd615f67c678a4b8ed54c11e4d6e917baa3560a6787ac7d4cd835430c16d
7
+ data.tar.gz: 96b6e87a78cd4c93113d385f53ec37062f56fc031e1e563ca6f0b0fd67b4c95e1432a35f3dd4bc49b272470091179dc428c17b76b8b11da37e072e05e5275f22
@@ -11,8 +11,8 @@ module Sequel
11
11
 
12
12
  if order.nil? || order.length.zero?
13
13
  raise Error, "cannot seek_paginate on a dataset with no order"
14
- elsif from && after
15
- raise Error, "cannot pass both :from and :after params to seek_paginate"
14
+ elsif [from, after, from_pk, after_pk].compact.count > 1
15
+ raise Error, "cannot pass more than one of the :from, :after, :from_pk and :after_pk arguments to seek_paginate"
16
16
  elsif model.nil? && (from_pk || after_pk)
17
17
  raise Error, "passed the :#{from_pk ? 'from' : 'after'}_pk option to seek_paginate on a dataset that doesn't have an associated model"
18
18
  end
@@ -26,11 +26,14 @@ module Sequel
26
26
  raise Error, "passed the wrong number of values in the :#{from ? 'from' : 'after'} option to seek_paginate"
27
27
  end
28
28
  elsif pk = from_pk || after_pk
29
- # Need to load the order expressions for that pk from the DB.
30
- selections = order.map { |o| Sequel::SQL::OrderedExpression === o ? o.expression : o }
29
+ # Need to load the values to order from for that pk from the DB, so we
30
+ # need to fetch the actual expressions being ordered by.
31
+ expressions = order.map { |o| Sequel::SQL::OrderedExpression === o ? o.expression : o }
31
32
 
32
- # #get won't like it if we pass it bare expressions, so give it aliases for everything.
33
- gettable = selections.zip(:a..:z).map{|s,a| Sequel.as(s, a)}
33
+ # Dataset#get won't like it if we pass it expressions that aren't
34
+ # simple columns, so give it aliases for everything.
35
+ al = :a
36
+ gettable = expressions.map.with_index{|s,i| Sequel.as(s, (al = al.next))}
34
37
 
35
38
  values = where(model.qualified_primary_key_hash(pk)).get(gettable)
36
39
  end
@@ -74,9 +77,13 @@ module Sequel
74
77
  # Handle the common case where we can do a simpler (and faster)
75
78
  # WHERE (non_nullable_1, non_nullable_2) > (1, 2) clause.
76
79
  if length > 1 && orders.all?(&:not_null) && has_uniform_order_direction?
77
- method = orders.first.direction == :asc ? '>' : '<'
78
- method << '='.freeze if include_exact_match
79
- Sequel.virtual_row{|o| o.__send__(method, orders.map(&:name), orders.map(&:value))}
80
+ Sequel.virtual_row do |o|
81
+ o.__send__(
82
+ orders.first.inequality_method(include_exact_match),
83
+ orders.map(&:name),
84
+ orders.map(&:value)
85
+ )
86
+ end
80
87
  else
81
88
  Sequel.&(
82
89
  *length.times.map { |i|
@@ -148,12 +155,11 @@ module Sequel
148
155
  {name => nil}
149
156
  end
150
157
 
151
- def ineq(eq: true)
158
+ def ineq(eq:)
152
159
  nulls_upcoming = !not_null && nulls == :last
153
160
 
154
161
  if !value.nil?
155
- method = "#{direction == :asc ? '>' : '<'}#{'=' if eq}"
156
- filter = Sequel.virtual_row{|o| o.__send__(method, name, value)}
162
+ filter = Sequel.virtual_row{|o| o.__send__(inequality_method(eq), name, value)}
157
163
  nulls_upcoming ? Sequel.|(filter, null_filter) : filter
158
164
  else
159
165
  if nulls_upcoming && eq
@@ -164,6 +170,14 @@ module Sequel
164
170
  end
165
171
  end
166
172
 
173
+ def inequality_method(eq)
174
+ case direction
175
+ when :asc then eq ? :>= : :>
176
+ when :desc then eq ? :<= : :<
177
+ else raise "Bad direction: #{direction.inspect}"
178
+ end
179
+ end
180
+
167
181
  private
168
182
 
169
183
  # By default, Postgres sorts NULLs as higher than any other value. So we
@@ -1,5 +1,5 @@
1
1
  module Sequel
2
2
  module SeekPagination
3
- VERSION = '0.1.0'
3
+ VERSION = '0.2.0'
4
4
  end
5
5
  end
@@ -27,7 +27,7 @@ class SeekPaginationSpec < Minitest::Spec
27
27
  dataset = dataset.order(*ordering)
28
28
 
29
29
  # Can't pass any random expression to #get, so give them all aliases.
30
- gettable = columns.zip(:a..:z).map{|c,a| c.as(a)}
30
+ gettable = columns.zip(:a..:z).map{|c,a| Sequel.as(c, a)}
31
31
 
32
32
  it "should limit the dataset appropriately when a starting point is not given" do
33
33
  assert_equal_results dataset.limit(10),
@@ -83,23 +83,23 @@ class SeekPaginationSpec < Minitest::Spec
83
83
  end
84
84
 
85
85
  describe "for ordering by a single not-null column in either order" do
86
- [:id.asc, :id.desc].each do |o1|
86
+ [Sequel.asc(:id), Sequel.desc(:id)].each do |o1|
87
87
  it_should_seek_paginate_properly [o1]
88
88
  end
89
89
  end
90
90
 
91
91
  describe "for ordering by two not-null columns in any order" do
92
- [:not_nullable_1.asc, :not_nullable_1.desc].each do |o1|
93
- [:id.asc, :id.desc].each do |o2|
92
+ [Sequel.asc(:not_nullable_1), Sequel.desc(:not_nullable_1)].each do |o1|
93
+ [Sequel.asc(:id), Sequel.desc(:id)].each do |o2|
94
94
  it_should_seek_paginate_properly [o1, o2]
95
95
  end
96
96
  end
97
97
  end
98
98
 
99
99
  describe "for ordering by three not-null columns in any order" do
100
- [:not_nullable_1.asc, :not_nullable_1.desc].each do |o1|
101
- [:not_nullable_2.asc, :not_nullable_2.desc].each do |o2|
102
- [:id.asc, :id.desc].each do |o3|
100
+ [Sequel.asc(:not_nullable_1), Sequel.desc(:not_nullable_1)].each do |o1|
101
+ [Sequel.asc(:not_nullable_2), Sequel.desc(:not_nullable_2)].each do |o2|
102
+ [Sequel.asc(:id), Sequel.desc(:id)].each do |o3|
103
103
  it_should_seek_paginate_properly [o1, o2, o3]
104
104
  end
105
105
  end
@@ -108,8 +108,8 @@ class SeekPaginationSpec < Minitest::Spec
108
108
 
109
109
  describe "for ordering by a nullable column" do
110
110
  # We still tack on :id because the ordering needs to be unique.
111
- [:nullable_1.asc, :nullable_1.desc, :nullable_1.asc(nulls: :first), :nullable_1.desc(nulls: :last)].each do |o1|
112
- [:id.asc, :id.desc].each do |o2|
111
+ [Sequel.asc(:nullable_1), Sequel.desc(:nullable_1), Sequel.asc(:nullable_1, nulls: :first), Sequel.desc(:nullable_1, nulls: :last)].each do |o1|
112
+ [Sequel.asc(:id), Sequel.desc(:id)].each do |o2|
113
113
  it_should_seek_paginate_properly [o1, o2]
114
114
  end
115
115
  end
@@ -117,9 +117,9 @@ class SeekPaginationSpec < Minitest::Spec
117
117
 
118
118
  describe "for ordering by multiple nullable columns" do
119
119
  # We still tack on :id because the ordering needs to be unique.
120
- [:nullable_1.asc, :nullable_1.desc, :nullable_1.asc(nulls: :first), :nullable_1.desc(nulls: :last)].each do |o1|
121
- [:nullable_2.asc, :nullable_2.desc, :nullable_2.asc(nulls: :first), :nullable_2.desc(nulls: :last)].each do |o2|
122
- [:id.asc, :id.desc].each do |o3|
120
+ [Sequel.asc(:nullable_1), Sequel.desc(:nullable_1), Sequel.asc(:nullable_1, nulls: :first), Sequel.desc(:nullable_1, nulls: :last)].each do |o1|
121
+ [Sequel.asc(:nullable_2), Sequel.desc(:nullable_2), Sequel.asc(:nullable_2, nulls: :first), Sequel.desc(:nullable_2, nulls: :last)].each do |o2|
122
+ [Sequel.asc(:id), Sequel.desc(:id)].each do |o3|
123
123
  it_should_seek_paginate_properly [o1, o2, o3]
124
124
  end
125
125
  end
@@ -129,14 +129,14 @@ class SeekPaginationSpec < Minitest::Spec
129
129
  describe "for ordering by a mix of nullable and not-nullable columns" do
130
130
  20.times do
131
131
  columns = [
132
- [:not_nullable_1, :not_nullable_1.asc, :not_nullable_1.desc],
133
- [:not_nullable_2, :not_nullable_2.asc, :not_nullable_2.desc],
134
- [:nullable_1, :nullable_1.asc, :nullable_1.desc, :nullable_1.asc(nulls: :first), :nullable_1.desc(nulls: :last)],
135
- [:nullable_2, :nullable_2.asc, :nullable_2.desc, :nullable_2.asc(nulls: :first), :nullable_2.desc(nulls: :last)],
132
+ [:not_nullable_1, Sequel.asc(:not_nullable_1), Sequel.desc(:not_nullable_1)],
133
+ [:not_nullable_2, Sequel.asc(:not_nullable_2), Sequel.desc(:not_nullable_2)],
134
+ [:nullable_1, Sequel.asc(:nullable_1), Sequel.desc(:nullable_1), Sequel.asc(:nullable_1, nulls: :first), Sequel.desc(:nullable_1, nulls: :last)],
135
+ [:nullable_2, Sequel.asc(:nullable_2), Sequel.desc(:nullable_2), Sequel.asc(:nullable_2, nulls: :first), Sequel.desc(:nullable_2, nulls: :last)],
136
136
  ]
137
137
 
138
138
  testing_columns = columns.sample(rand(columns.count) + 1).map(&:sample)
139
- testing_columns << [:id, :id.asc, :id.desc].sample
139
+ testing_columns << [:id, Sequel.asc(:id), Sequel.desc(:id)].sample
140
140
 
141
141
  it_should_seek_paginate_properly(testing_columns)
142
142
  end
@@ -145,14 +145,14 @@ class SeekPaginationSpec < Minitest::Spec
145
145
  describe "for ordering by a mix of expressions and columns" do
146
146
  20.times do
147
147
  columns = [
148
- [:not_nullable_1, :not_nullable_1.asc, :not_nullable_1.desc, :not_nullable_1.sql_number % 10, (:not_nullable_1.sql_number % 10).asc, (:not_nullable_1.sql_number % 10).desc],
149
- [:not_nullable_2, :not_nullable_2.asc, :not_nullable_2.desc, :not_nullable_2.sql_number % 10, (:not_nullable_2.sql_number % 10).asc, (:not_nullable_2.sql_number % 10).desc],
150
- [:nullable_1, :nullable_1.asc, :nullable_1.desc, :nullable_1.asc(nulls: :first), :nullable_1.desc(nulls: :last), :nullable_1.sql_number % 10, (:nullable_1.sql_number % 10).asc, (:nullable_1.sql_number % 10).desc, (:nullable_1.sql_number % 10).asc(nulls: :first), (:nullable_1.sql_number % 10).desc(nulls: :last)],
151
- [:nullable_2, :nullable_2.asc, :nullable_2.desc, :nullable_2.asc(nulls: :first), :nullable_2.desc(nulls: :last), :nullable_2.sql_number % 10, (:nullable_2.sql_number % 10).asc, (:nullable_2.sql_number % 10).desc, (:nullable_2.sql_number % 10).asc(nulls: :first), (:nullable_2.sql_number % 10).desc(nulls: :last)],
148
+ [:not_nullable_1, Sequel.asc(:not_nullable_1), Sequel.desc(:not_nullable_1), Sequel.expr(:not_nullable_1).sql_number % 10, Sequel.asc(Sequel.expr(:not_nullable_1).sql_number % 10), Sequel.desc(Sequel.expr(:not_nullable_1).sql_number % 10)],
149
+ [:not_nullable_2, Sequel.asc(:not_nullable_2), Sequel.desc(:not_nullable_2), Sequel.expr(:not_nullable_2).sql_number % 10, Sequel.asc(Sequel.expr(:not_nullable_2).sql_number % 10), Sequel.desc(Sequel.expr(:not_nullable_2).sql_number % 10)],
150
+ [:nullable_1, Sequel.asc(:nullable_1), Sequel.desc(:nullable_1), Sequel.asc(:nullable_1, nulls: :first), Sequel.desc(:nullable_1, nulls: :last), Sequel.expr(:nullable_1).sql_number % 10, Sequel.asc(Sequel.expr(:nullable_1).sql_number % 10), (Sequel.expr(:nullable_1).sql_number % 10).desc, Sequel.asc(Sequel.expr(:nullable_1).sql_number % 10, nulls: :first), Sequel.desc(Sequel.expr(:nullable_1).sql_number % 10, nulls: :last)],
151
+ [:nullable_2, Sequel.asc(:nullable_2), Sequel.desc(:nullable_2), Sequel.asc(:nullable_2, nulls: :first), Sequel.desc(:nullable_2, nulls: :last), Sequel.expr(:nullable_2).sql_number % 10, Sequel.asc(Sequel.expr(:nullable_2).sql_number % 10), (Sequel.expr(:nullable_2).sql_number % 10).desc, Sequel.asc(Sequel.expr(:nullable_2).sql_number % 10, nulls: :first), Sequel.desc(Sequel.expr(:nullable_2).sql_number % 10, nulls: :last)],
152
152
  ]
153
153
 
154
154
  testing_columns = columns.sample(rand(columns.count) + 1).map(&:sample)
155
- testing_columns << [:id, :id.asc, :id.desc].sample
155
+ testing_columns << [:id, Sequel.asc(:id), Sequel.desc(:id)].sample
156
156
 
157
157
  it_should_seek_paginate_properly(testing_columns)
158
158
  end
@@ -162,10 +162,10 @@ class SeekPaginationSpec < Minitest::Spec
162
162
  datasets = [
163
163
  DB[:seek].order(:id),
164
164
  DB[:seek].order(:seek__id),
165
- DB[:seek].order(:id.asc),
166
- DB[:seek].order(:seek__id.asc),
167
- DB[:seek].order(:id.desc).reverse_order,
168
- DB[:seek].order(:seek__id.desc).reverse_order,
165
+ DB[:seek].order(Sequel.asc(:id)),
166
+ DB[:seek].order(Sequel.asc(:seek__id)),
167
+ DB[:seek].order(Sequel.desc(:id)).reverse_order,
168
+ DB[:seek].order(Sequel.desc(:seek__id)).reverse_order,
169
169
  ]
170
170
 
171
171
  # With point to start from/after:
@@ -187,8 +187,11 @@ class SeekPaginationSpec < Minitest::Spec
187
187
  assert_error_message("cannot seek_paginate on a dataset with no order") { DB[:seek].seek_paginate(30) }
188
188
  end
189
189
 
190
- it "should raise an error if the dataset is not ordered" do
191
- assert_error_message("cannot pass both :from and :after params to seek_paginate") { DB[:seek].order(:id).seek_paginate(30, from: 3, after: 4) }
190
+ it "should raise an error if more than one location argument is passed to seek_paginate" do
191
+ assert_error_message("cannot pass more than one of the :from, :after, :from_pk and :after_pk arguments to seek_paginate") { DB[:seek].order(:id).seek_paginate(30, from: 3, after: 4) }
192
+ assert_error_message("cannot pass more than one of the :from, :after, :from_pk and :after_pk arguments to seek_paginate") { DB[:seek].order(:id).seek_paginate(30, from_pk: 3, after_pk: 4) }
193
+ assert_error_message("cannot pass more than one of the :from, :after, :from_pk and :after_pk arguments to seek_paginate") { DB[:seek].order(:id).seek_paginate(30, from: 3, after_pk: 4) }
194
+ assert_error_message("cannot pass more than one of the :from, :after, :from_pk and :after_pk arguments to seek_paginate") { DB[:seek].order(:id).seek_paginate(30, from_pk: 3, after: 4) }
192
195
  end
193
196
 
194
197
  it "should raise an error if given the wrong number of values to from or after" do
data/spec/spec_helper.rb CHANGED
@@ -2,8 +2,6 @@ require 'sequel'
2
2
 
3
3
  $: << File.join(File.dirname(__FILE__), '..', 'lib')
4
4
 
5
- Sequel.extension :core_extensions
6
-
7
5
  Sequel::Database.extension :seek_pagination
8
6
 
9
7
  DB = Sequel.connect "postgres:///sequel-seek-pagination-test"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel-seek-pagination
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Hanks
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-03 00:00:00.000000000 Z
11
+ date: 2015-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler