cursor_pager 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
  SHA256:
3
- metadata.gz: 1cfa8e486f765f437f2737c1778ea9f70c22849d8e0a6912bee1ec20440487a2
4
- data.tar.gz: 99bbe1f36e20d8574217ca27f6bec0ef431487679f048ce7e6fb55fb8c73de5e
3
+ metadata.gz: 2cae99728d5827015878e6af2b7e5b06851984dec3e82f6b7ffce0e471ecab1c
4
+ data.tar.gz: 548d5f8799dd7748837a083ef9ec8cc8f620ede7a29107ddb7c20be28a64efb1
5
5
  SHA512:
6
- metadata.gz: fe4e2e39e9d28cb318b6da7d09368f2d866a2f5386e796f8f816af22fdada3539748c46e59259c51673eee30ddb5d6059d0e02a8f6800da936be6fe1db7af6ae
7
- data.tar.gz: 0e861720ee32d06b9d55c58a0f0a4ff6ba316435ae619186b8f762c42a6df40db87c79e7d968517d899fe3be3777dc146641dfa79dcada4f66883bc6e6686c48
6
+ metadata.gz: f84865be5f0153580346a191e58dc8483abc2a3699a358a38a2d6117624610c102fdde004b9a785b07b2095141be06e385416c5f0b94b30f2a22b0bfb1572c2d
7
+ data.tar.gz: e7131697760670148494e697db0579dc3d96486d09fe945552bbe22d824654afb827c0392e86099725aa48a8c72d8e4c26bcc0ffb5ffcb77561c490a09c47390
data/.rubocop.yml CHANGED
@@ -18,5 +18,8 @@ Metrics/BlockLength:
18
18
  Exclude:
19
19
  - /**/spec/**/*
20
20
 
21
+ Metrics/ClassLength:
22
+ Max: 200
23
+
21
24
  Style/StringLiterals:
22
25
  EnforcedStyle: double_quotes
data/CHANGELOG.md CHANGED
@@ -5,4 +5,22 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## Unreleased
8
+ ## [Unreleased]
9
+
10
+ ## [0.2.0] - 2020-04-23
11
+
12
+ ### Added
13
+
14
+ * `first_cursor` & `last_cursor` convenience methods
15
+ * Configurable default & maximum page sizes #6
16
+
17
+ ## [0.1.0] - 2020-04-23
18
+
19
+ ### Added
20
+
21
+ * First implementation of cursor-pased pagination #2
22
+ * Configurable cursor encoder #3
23
+
24
+ [Unreleased]: https://github.com/askcharlie/cursor_pager/compare/v0.2.0...HEAD
25
+ [0.2.0]: https://github.com/askcharlie/cursor_pager/compare/v0.1.0...v0.2.0
26
+ [0.1.0]: https://github.com/askcharlie/cursor_pager/releases/tag/v0.1.0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cursor_pager (0.1.0)
4
+ cursor_pager (0.2.0)
5
5
  activerecord (>= 5.2.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # CursorPager
2
2
 
3
- ![build](https://github.com/askcharlie/cursor_pager/workflows/CI/badge.svg)
3
+ ![build](https://github.com/askcharlie/cursor_pager/workflows/CI/badge.svg) [![Gem Version](https://badge.fury.io/rb/cursor_pager.svg)](https://badge.fury.io/rb/cursor_pager)
4
4
 
5
5
  A small and easy-to-use library that aims to make it easy to build Rails APIs
6
6
  with cursor-based pagination (aka keyset pagination).
@@ -45,7 +45,9 @@ To get information about the page or generate a cursor
45
45
  ```ruby
46
46
  page.previous_page? # Tells you if there is a previous page
47
47
  page.next_page? # Tells you if there is a next page
48
- page.cursor_for(page.records.last) # Will generate a cursor for a specific item
48
+ page.cursor_for(page.records.last) # Generates a cursor for a specific item
49
+ page.first_cursor # Generates a cursor for the first item
50
+ page.last_cursor # Generates a cursor for the last item
49
51
  ```
50
52
 
51
53
  To fetch the first then usres after a certain cursor
@@ -65,6 +67,8 @@ page.records
65
67
 
66
68
  ## Configuration
67
69
 
70
+ ### Encoder
71
+
68
72
  By default cursors are base64 encoded primary keys of the records. If you wish
69
73
  to change that because you want to add encryption or something similiar, you
70
74
  can provide your own encoder class.
@@ -85,6 +89,18 @@ CursorPager.configure do |config|
85
89
  end
86
90
  ```
87
91
 
92
+ ### Default & Maximum Page Size
93
+
94
+ The default & maximum page sizes are configured as `nil` (unlimited) by default.
95
+ You can however set your own values.
96
+
97
+ ```ruby
98
+ CursorPager.configure do |config|
99
+ config.default_page_size = 25
100
+ config.maximum_page_size = 100
101
+ end
102
+ ```
103
+
88
104
  ## Not (yet) supported
89
105
 
90
106
  * Ordering by SQL alias or function
@@ -5,10 +5,24 @@ module CursorPager
5
5
  # Encapulates all the configuration for the library.
6
6
  class Configuration
7
7
  # The encoder that will be used to encode & decode cursors.
8
+ # Defaults to `Base64Encoder`.
8
9
  attr_accessor :encoder
9
10
 
11
+ # The default page size that will be used if no `first` or `last` were
12
+ # specified. Every record fitting the cursor constraints will be returned
13
+ # if it's set to `nil`.
14
+ # Defaults to `nil`.
15
+ attr_accessor :default_page_size
16
+
17
+ # The maximum allowed page size. Clients will never receive more records per
18
+ # page than is sepcified here. There is no maximum if this is set to `nil`.
19
+ # Defaults to `nil`.
20
+ attr_accessor :maximum_page_size
21
+
10
22
  def initialize
11
23
  @encoder = Base64Encoder
24
+ @default_page_size = nil
25
+ @maximum_page_size = nil
12
26
  end
13
27
  end
14
28
 
@@ -3,12 +3,19 @@
3
3
  module CursorPager
4
4
  # The main class that coordinates the whole pagination.
5
5
  class Page
6
- attr_reader :relation, :first, :last, :after, :before, :order_values
6
+ extend Forwardable
7
+
8
+ attr_reader :relation, :first_value, :last_value, :after, :before,
9
+ :order_values
10
+
11
+ def_delegators :@configuration, :encoder, :default_page_size,
12
+ :maximum_page_size
7
13
 
8
14
  def initialize(relation, first: nil, last: nil, after: nil, before: nil)
15
+ @configuration = CursorPager.configuration
9
16
  @relation = relation
10
- @first = first
11
- @last = last
17
+ @first_value = first
18
+ @last_value = last
12
19
  @after = after
13
20
  @before = before
14
21
  @order_values = OrderValues.from_relation(relation)
@@ -17,6 +24,28 @@ module CursorPager
17
24
  verify_order_directions!
18
25
  end
19
26
 
27
+ # A capped `first` value.
28
+ # The underlying instance variable `first_value` doesn't have limits on it.
29
+ # If neither `first` nor `last` is given, but `default_page_size` or
30
+ # `maximum_page_size` are configured, they will be used for first.
31
+ def first
32
+ @first ||= begin
33
+ capped = limit_pagination_argument(first_value)
34
+
35
+ if capped.nil? && last.nil?
36
+ capped = default_page_size || maximum_page_size
37
+ end
38
+
39
+ capped
40
+ end
41
+ end
42
+
43
+ # A capped `last` value.
44
+ # The underlying instance variable `last_value` doesn't have limits on it.
45
+ def last
46
+ @last ||= limit_pagination_argument(last_value)
47
+ end
48
+
20
49
  def previous_page?
21
50
  @previous_page ||= if after_limit_value.present?
22
51
  true
@@ -38,9 +67,19 @@ module CursorPager
38
67
  end
39
68
 
40
69
  def cursor_for(item)
70
+ return if item.nil?
71
+
41
72
  encoder.encode(item.id.to_s)
42
73
  end
43
74
 
75
+ def first_cursor
76
+ cursor_for(records.first)
77
+ end
78
+
79
+ def last_cursor
80
+ cursor_for(records.last)
81
+ end
82
+
44
83
  def records
45
84
  @records ||= limited_relation.to_a
46
85
  end
@@ -67,6 +106,21 @@ module CursorPager
67
106
  raise ConflictingOrdersError
68
107
  end
69
108
 
109
+ # Used to cap `first` and `last` arguments.
110
+ # Returns `nil` if the argument is `nil`, otherwise a value between `0` and
111
+ # `maximum_page_size`.
112
+ def limit_pagination_argument(argument)
113
+ return if argument.nil?
114
+
115
+ if argument.negative?
116
+ argument = 0
117
+ elsif maximum_page_size && argument > maximum_page_size
118
+ argument = maximum_page_size
119
+ end
120
+
121
+ argument
122
+ end
123
+
70
124
  def limited_relation
71
125
  @limited_relation ||= LimitRelation.new(sliced_relation, first, last).call
72
126
  end
@@ -102,9 +156,5 @@ module CursorPager
102
156
 
103
157
  order_values.map { |value| item[value.select_alias] }
104
158
  end
105
-
106
- def encoder
107
- CursorPager.configuration.encoder
108
- end
109
159
  end
110
160
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CursorPager
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cursor_pager
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
  - Bastian Bartmann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-23 00:00:00.000000000 Z
11
+ date: 2020-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord