Skip to content

Commit 57d02fa

Browse files
committed
WIP: Super refactoring 2
1 parent 6499969 commit 57d02fa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+483
-359
lines changed

Gemfile.lock

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ PATH
33
specs:
44
pagy (9.3.3)
55
json
6+
yaml
67

78
GEM
89
remote: https://rubygems.org/
@@ -87,7 +88,7 @@ GEM
8788
bigdecimal (3.1.9)
8889
builder (3.3.0)
8990
concurrent-ruby (1.3.4)
90-
connection_pool (2.4.1)
91+
connection_pool (2.5.0)
9192
crass (1.0.6)
9293
date (3.4.1)
9394
docile (1.4.1)
@@ -321,6 +322,7 @@ GEM
321322
base64
322323
websocket-extensions (>= 0.1.0)
323324
websocket-extensions (0.1.5)
325+
yaml (0.4.0)
324326
zeitwerk (2.7.1)
325327

326328
PLATFORMS

gem/lib/pagy.rb

+12-60
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,20 @@
22
# frozen_string_literal: true
33

44
require 'pathname'
5-
require_relative 'pagy/autoloading'
5+
require_relative 'pagy/autoload'
66

77
# Top superclass: it should define only what's common to all the subclasses
88
class Pagy
9+
autoload :Backend, 'pagy/backend'
10+
autoload :Frontend, 'pagy/frontend'
11+
autoload :I18n, 'pagy/i18n'
12+
autoload :UISupport, 'pagy/ui_support'
13+
autoload :Offset, 'pagy/offset'
14+
autoload :Keyset, 'pagy/keyset'
15+
autoload :ElasticsearchRails, 'pagy/mixins/elasticsearch_rails'
16+
autoload :Meilisearch, 'pagy/mixins/meilisearch'
17+
autoload :Searchkick, 'pagy/mixins/searchkick'
18+
919
VERSION = '9.3.3'
1020
PAGE_TOKEN = 'P '
1121
LABEL_TOKEN = 'L'
@@ -41,66 +51,8 @@ def assign_vars(vars)
4151
cclass = cclass.superclass
4252
default = cclass::DEFAULT.merge(default)
4353
end
44-
@vars = { **default, **vars.delete_if { |k, v| default.key?(k) && (v.nil? || v == '') } }
45-
end
46-
47-
# Shared with KeysetForUI
48-
module SharedUIMethods
49-
attr_reader :in, :last, :prev
50-
alias pages last
51-
52-
# Label for the current page. Allow the customization of the output (overridden by the calendar extra)
53-
def label = @page.to_s
54-
55-
# Label for any page. Allow the customization of the output (overridden by the calendar extra)
56-
def label_for(page) = page.to_s
57-
58-
# Return the array of page numbers and :gap e.g. [1, :gap, 8, "9", 10, :gap, 36]
59-
def series(size: @vars[:size], **_)
60-
raise VariableError.new(self, :size, 'to be an Integer >= 0', size) \
61-
unless size.is_a?(Integer) && size >= 0
62-
return [] if size.zero?
63-
64-
[].tap do |series|
65-
if size >= @last
66-
series.push(*1..@last)
67-
else
68-
left = ((size - 1) / 2.0).floor # left half might be 1 page shorter for even size
69-
start = if @page <= left # beginning pages
70-
1
71-
elsif @page > (@last - size + left) # end pages
72-
@last - size + 1
73-
else
74-
# intermediate pages
75-
@page - left
76-
end
77-
series.push(*start...start + size)
78-
# Set first and last pages plus gaps when needed, respecting the size
79-
if vars[:ends] && size >= 7
80-
series[0] = 1
81-
series[1] = :gap unless series[1] == 2
82-
series[-2] = :gap unless series[-2] == @last - 1
83-
series[-1] = @last
84-
end
85-
end
86-
series[series.index(@page)] = @page.to_s unless @overflow # overflow has no current page
87-
end
88-
end
89-
90-
# `Pagy` instance method used by the `pagy*_nav_js` helpers.
91-
# Return the reverse sorted array of widths, series, and labels generated from the :steps hash
92-
# Notice: if :steps is false it will use the single {0 => @vars[:size]} size
93-
def sequels(steps: @vars[:steps] || { 0 => @vars[:size] }, **_)
94-
raise VariableError.new(self, :steps, 'to define the 0 width', steps) unless steps.key?(0)
95-
96-
widths, series = steps.sort.reverse.map { |width, size| [width, series(size:)] }.transpose
97-
[widths, series, label_sequels(series)]
98-
end
99-
100-
# Support for the Calendar API
101-
def label_sequels(*); end
54+
@vars = { **default, **vars.delete_if { |k, v| default.key?(k) && (v.nil? || v == '') } }
10255
end
103-
include Autoloading
10456
end
10557

10658
require_relative 'pagy/exceptions'

gem/lib/pagy/autoloading.rb gem/lib/pagy/autoload.rb

+4-12
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
11
# frozen_string_literal: true
22

33
class Pagy
4-
autoload :Frontend, 'pagy/frontend'
5-
autoload :Backend, 'pagy/backend'
6-
autoload :Offset, 'pagy/offset'
7-
autoload :Keyset, 'pagy/keyset'
8-
autoload :ElasticsearchRails, 'pagy/mixin/elasticsearch_rails'
9-
autoload :Meilisearch, 'pagy/mixin/meilisearch'
10-
autoload :Searchkick, 'pagy/mixin/searchkick'
11-
12-
module Autoloading
4+
module Autoload
135
METHOD_MIXINS = { pagy_arel: :arel,
146
pagy_array: :array,
157
pagy_bootstrap_nav: :bootstrap,
@@ -20,11 +12,11 @@ module Autoloading
2012
pagy_bulma_combo_nav_js: :bulma,
2113
pagy_calendar: :calendar,
2214
pagy_countless: :countless,
23-
new_from_elasticserch_rails: :elasticsearch,
15+
new_from_elasticserch_rails: :elasticsearch_rails,
2416
pagy_elasticsearch_rails: :elasticsearch_rails,
2517
pagy_headers: :headers,
2618
pagy_headers_merge: :headers,
27-
pagy_keyset: :keysets,
19+
pagy_keyset: :keyset,
2820
pagy_keyset_augmented_js: :keyset_augmented,
2921
new_from_meilisearch: :meilisearch,
3022
pagy_meilisearch: :meilisearch,
@@ -48,7 +40,7 @@ def respond_to_missing?(method, ...)
4840
def method_missing(method, ...)
4941
return super unless respond_to?(method)
5042

51-
require_relative "mixin/#{METHOD_MIXINS[method]}"
43+
require_relative "mixins/#{METHOD_MIXINS[method]}"
5244
send(method, ...)
5345
end
5446
end

gem/lib/pagy/backend.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ class Pagy
88
# or any collection by overriding any of the `pagy_*` methods in your controller.
99
# See also the extras if you need specialized methods to paginate Arrays or other collections
1010
module Backend
11-
include Pagy::Autoloading
11+
include Autoload
12+
1213
private
1314

1415
# Sub-method called only by #pagy: here for easy customization of fetching by overriding

gem/lib/pagy/extras/gearbox.rb

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ class Pagy
1010
# Automatically change the limit depending on the page number
1111
# accepts an array as the :gearbox_limit variable, that will determine the limit for the first pages
1212
module GearboxExtra
13-
1413
module OffsetOverride
1514
# Assign @limit based on the :gearbox_limit variable
1615
def assign_limit

gem/lib/pagy/extras/jsonapi.rb

+3-13
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# frozen_string_literal: true
33

44
require_relative '../url_helpers'
5+
require_relative '../links_helper'
56

67
class Pagy
78
DEFAULT[:jsonapi] = true
@@ -21,21 +22,10 @@ module BackendOverride
2122
private
2223

2324
include UrlHelpers
25+
include LinksHelper
2426

2527
# Return the jsonapi links
26-
def pagy_jsonapi_links(pagy, **)
27-
if defined?(::Pagy::Keyset) && pagy.is_a?(Keyset)
28-
{ first: pagy_page_url(pagy, nil, **),
29-
last: nil,
30-
prev: nil,
31-
next: pagy.next ? pagy_page_url(pagy, pagy.next, **) : nil }
32-
else
33-
{ first: pagy_page_url(pagy, 1, **),
34-
last: pagy_page_url(pagy, pagy.last, **),
35-
prev: pagy.prev ? pagy_page_url(pagy, pagy.prev, **) : nil,
36-
next: pagy.next ? pagy_page_url(pagy, pagy.next, **) : nil }
37-
end
38-
end
28+
alias pagy_jsonapi_links pagy_links
3929

4030
# Should skip the jsonapi
4131
def pagy_skip_jsonapi?(vars)

gem/lib/pagy/frontend.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
# See Pagy::Frontend API documentation: https://ddnexus.github.io/pagy/docs/api/frontend
22
# frozen_string_literal: true
33

4+
require_relative 'b64'
45
require_relative 'i18n'
56
require_relative 'url_helpers'
67

78
class Pagy
89
# Frontend modules are specially optimized for performance.
910
# The resulting code may not look very elegant, but produces the best benchmarks
1011
module Frontend
11-
include Pagy::Autoloading
12+
include Autoload
1213
include UrlHelpers
1314

1415
# Return a performance optimized lambda to generate the HTML anchor element (a tag)

gem/lib/pagy/keyset.rb

+3-13
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,15 @@
44
require 'json'
55
require_relative 'b64'
66

7-
require_relative 'keyset/adapters/active_record'
8-
require_relative 'keyset/adapters/sequel'
9-
107
class Pagy
118
# Implement wicked-fast keyset pagination for big data
129
class Keyset < Pagy
13-
14-
autoload :Augmented, 'pagy/keyset/augmented'
10+
autoload :ActiveRecord, 'pagy/keyset/active_record'
11+
autoload :Sequel, 'pagy/keyset/sequel'
12+
autoload :Augmented, 'pagy/keyset/augmented'
1513

1614
class TypeError < ::TypeError; end
1715

18-
class ActiveRecord < Keyset
19-
include Adapters::ActiveRecord
20-
end
21-
22-
class Sequel < Keyset
23-
include Adapters::Sequel
24-
end
25-
2616
# Pick the right adapter for the set and initilize the right class
2717
def self.new(set, **vars)
2818
if self == Pagy::Keyset || (defined?(::Pagy::Keyset::Augmented) && self == ::Pagy::Keyset::Augmented)

gem/lib/pagy/keyset/active_record.rb

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# frozen_string_literal: true
2+
3+
require_relative 'active_record_adapter'
4+
5+
class Pagy
6+
class Keyset
7+
class ActiveRecord < Keyset
8+
include ActiveRecordAdapter
9+
end
10+
end
11+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# See Pagy API documentation: https://ddnexus.github.io/pagy/docs/api/keyset
2+
# frozen_string_literal: true
3+
4+
class Pagy
5+
class Keyset < Pagy
6+
# Keyset adapter for ActiveRecord
7+
module ActiveRecordAdapter
8+
# Append the missing keyset keys if the set is restricted by select
9+
def apply_select
10+
@set.select(*@keyset.keys)
11+
end
12+
13+
# Extract the keyset from the set
14+
def extract_keyset
15+
@set.order_values.each_with_object({}) do |node, keyset|
16+
keyset[node.value.name.to_sym] = node.direction
17+
end
18+
end
19+
20+
# Filter the page records
21+
def filter_records = @set.where(after_cutoff_sql, **@filter_args)
22+
23+
# Get the keyset attributes from the record
24+
def keyset_attributes_from(record) = record.slice(*@keyset.keys)
25+
26+
# Set with selected columns?
27+
def select? = !@set.select_values.empty?
28+
29+
# Typecast the cut args
30+
def typecast_args(args)
31+
@set.model.new(args).slice(args.keys)
32+
.to_hash.transform_keys(&:to_sym)
33+
end
34+
end
35+
end
36+
end

gem/lib/pagy/keyset/adapters/active_record.rb

-38
This file was deleted.

gem/lib/pagy/keyset/adapters/sequel.rb

-51
This file was deleted.

0 commit comments

Comments
 (0)