rotulus 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -3
- data/README.md +4 -3
- data/lib/rotulus/order.rb +9 -0
- data/lib/rotulus/version.rb +1 -1
- data/lib/rotulus.rb +2 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c74625ece0961a25549797386fa66abb146564211b4dc1640abd92ac4c0e2a0
|
4
|
+
data.tar.gz: 567562c553bbe914cdf5740e4262bd76b59ef04493658a68c69bd420e3109283
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e1380f553f3a0756b36b21f2a6193ee7031fe29bc8b3478ec349f6c35d2b9292ed5afd295b6b5250b2dc4498e1d86b66d13d639ea5e3d36db78fc8868fb4e9f
|
7
|
+
data.tar.gz: 625359b428c792c30a2a2ee2b6b702a2c7270e495111c284c82a1d1433eddf5d0ac485d6d5ae961128006f161c4cb01b8fa76f7ab3bd14d63cb761306a9392f6
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
## 0.2.0
|
2
|
-
|
3
|
-
Initial release.
|
2
|
+
- Initial release.
|
4
3
|
|
5
4
|
## 0.2.1
|
5
|
+
- Drop unnecessary ORDER BY columns following a non-nullable and distinct column.
|
6
6
|
|
7
|
-
|
7
|
+
## 0.2.2
|
8
|
+
- Raise error when there is no non-nullable and distinct column in the configured order definition.
|
data/README.md
CHANGED
@@ -295,18 +295,19 @@ page = Rotulus::Page.new(items, order: order_by, limit: 2)
|
|
295
295
|
|
296
296
|
| Class | Description |
|
297
297
|
| ----------- | ----------- |
|
298
|
-
| `Rotulus::InvalidCursor` | Cursor token received is invalid e.g., unrecognized token, token data has been tampered/updated, base ActiveRecord relation filter/sorting/limit is no longer consistent to the token
|
298
|
+
| `Rotulus::InvalidCursor` | Cursor token received is invalid e.g., unrecognized token, token data has been tampered/updated, base ActiveRecord relation filter/sorting/limit is no longer consistent to the token. |
|
299
299
|
| `Rotulus::Expired` | Cursor token received has expired based on the configured `token_expires_in` |
|
300
300
|
| `Rotulus::InvalidLimit` | Limit set to Rotulus::Page is not valid. e.g., exceeds the configured limit. see `config.page_max_limit` |
|
301
301
|
| `Rotulus::CursorError` | Generic error for cursor related validations |
|
302
|
-
| `Rotulus::
|
302
|
+
| `Rotulus::InvalidColumnError` | Column provided in the :order param can't be found. |
|
303
|
+
| `Rotulus::MissingTiebreakerError` | There is no non-nullable and distinct column in the configured order definition. |
|
303
304
|
| `Rotulus::ConfigurationError` | Generic error for missing/invalid configurations. |
|
304
305
|
|
305
306
|
## How it works
|
306
307
|
Cursor-based pagination uses a reference point/record to fetch the previous or next set of records. This gem takes care of the SQL query and cursor generation needed for the pagination. To ensure that the pagination results are stable, it requires that:
|
307
308
|
|
308
309
|
* Records are sorted (`ORDER BY`).
|
309
|
-
* In case multiple records with the same column value(s) exists in the result, a unique column is needed as tie-breaker. Usually, the table PK suffices for this but for complex queries(e.g. with table joins and with nullable columns, etc.), combining and using multiple columns that would uniquely identify the row in the result is needed.
|
310
|
+
* In case multiple records with the same column value(s) exists in the result, a unique non-nullable column is needed as tie-breaker. Usually, the table PK suffices for this but for complex queries(e.g. with table joins and with nullable columns, etc.), combining and using multiple columns that would uniquely identify the row in the result is needed.
|
310
311
|
* Columns used in `ORDER BY` would need to be indexed as they will be used in filtering.
|
311
312
|
|
312
313
|
|
data/lib/rotulus/order.rb
CHANGED
@@ -11,6 +11,9 @@ module Rotulus
|
|
11
11
|
@definition = {}
|
12
12
|
|
13
13
|
build_column_definitions
|
14
|
+
|
15
|
+
return if has_tiebreaker?
|
16
|
+
raise Rotulus::MissingTiebreakerError.new('A non-nullable and distinct column is required.')
|
14
17
|
end
|
15
18
|
|
16
19
|
# Returns an array of the ordered columns
|
@@ -137,6 +140,12 @@ module Rotulus
|
|
137
140
|
)
|
138
141
|
end
|
139
142
|
|
143
|
+
def has_tiebreaker?
|
144
|
+
last_column = columns_for_order.last
|
145
|
+
|
146
|
+
last_column.distinct? && !last_column.nullable?
|
147
|
+
end
|
148
|
+
|
140
149
|
def primary_key_ordered?
|
141
150
|
!definition["#{ar_table}.#{ar_model_primary_key}"].nil?
|
142
151
|
end
|
data/lib/rotulus/version.rb
CHANGED
data/lib/rotulus.rb
CHANGED
@@ -21,7 +21,8 @@ module Rotulus
|
|
21
21
|
class InvalidCursorDirection < CursorError; end
|
22
22
|
class InvalidLimit < BaseError; end
|
23
23
|
class ConfigurationError < BaseError; end
|
24
|
-
class
|
24
|
+
class MissingTiebreakerError < ConfigurationError; end
|
25
|
+
class InvalidColumnError < ConfigurationError; end
|
25
26
|
|
26
27
|
def self.db
|
27
28
|
@db ||= case ActiveRecord::Base.connection.adapter_name.downcase
|