rotulus 0.2.1 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6bc659ce794517af485f9c65dc18467b4278c21e8813e612a0b4dcdabde0b10f
4
- data.tar.gz: 2dc66e54844499214cc07ae49d8ca0ad33586ba28a11d4e2a3a4366d4633525a
3
+ metadata.gz: 15fae43a1fc07b2c268c1604c065a12f0d2288d733219aa563348019a872d7a0
4
+ data.tar.gz: ca8548477eee36f6bed018d8ec20d5dd5217f74d36954f13b4e243fbaee6755e
5
5
  SHA512:
6
- metadata.gz: f60f971213d39e4baa5d6fd53227971df6e09fb87f1824487e17a2972e80803db29e2b5894cc7b0be659d73ad3bf959a5944c5ed0235b754f19a80afe0cd69e1
7
- data.tar.gz: f0b072563fe10c626772f2879d9533263b393452022a5e4547ea6e5413a5bfab92ef629dd3aa787328b3bda14ae89ae04e1d5c345073fe3ae2e2afc2092dae86
6
+ metadata.gz: f9d0e4611e800688f8c10ad7347043a07e7358f79a4254ecac6359a1f5f4101d323cfe0b21d45b363984cdc681e3ffc8b8b9587311e96553ab952eb76016792b
7
+ data.tar.gz: a3240e33d45cd4360c4235e94860558c584a9f1f373c9ad7451ad9d819c2616f5a2e2146bef0449b716b846144ee87c19e92596c2b39c13e34bef254f49c50af
data/CHANGELOG.md CHANGED
@@ -1,7 +1,11 @@
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
+
7
+ ## 0.2.2
8
+ - Raise error when there is no non-nullable and distinct column in the configured order definition.
6
9
 
7
- Drop unnecessary ORDER BY columns following a non-nullable and distinct column.
10
+ ## 0.2.3
11
+ - Replace any existing order defined on the given ar_relation
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:: InvalidColumnError` | Column provided in the :order param is can't be recognized. |
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/page.rb CHANGED
@@ -209,7 +209,7 @@ module Rotulus
209
209
  return @loaded_records unless @loaded_records.nil?
210
210
 
211
211
  @loaded_records = ar_relation.where(cursor&.sql)
212
- .order(order_by_sql)
212
+ .reorder(order_by_sql)
213
213
  .limit(limit + 1)
214
214
  .select(*select_columns)
215
215
  return @loaded_records.to_a unless paged_back?
@@ -1,3 +1,3 @@
1
1
  module Rotulus
2
- VERSION = '0.2.1'
2
+ VERSION = '0.2.3'
3
3
  end
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 InvalidColumnError < BaseError; end
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rotulus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Uy Jayson B
@@ -64,8 +64,8 @@ dependencies:
64
64
  - - ">="
65
65
  - !ruby/object:Gem::Version
66
66
  version: '0'
67
- description: Cursor-based pagination for apps built on Rails/ActiveRecord with sort
68
- by multiple columns support for a more stable and predictable pagination.
67
+ description: Cursor-based pagination for Rails/ActiveRecord apps with multiple column
68
+ sort and custom cursor format support for a more stable and predictable pagination.
69
69
  email:
70
70
  - uy.json.dev@gmail.com
71
71
  executables: []
@@ -116,6 +116,6 @@ requirements: []
116
116
  rubygems_version: 3.1.4
117
117
  signing_key:
118
118
  specification_version: 4
119
- summary: Cursor-based pagination for apps built on Rails/ActiveRecord with sort by
120
- multiple columns support.
119
+ summary: Cursor-based Rails/ActiveRecord pagination with multiple column sort and
120
+ custom cursor token format support.
121
121
  test_files: []