diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ff6d78..3e7b47a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,6 +37,9 @@ jobs: - ruby-version: 3.2 env: BUNDLE_GEMFILE: gemfiles/active_record_70.gemfile + - ruby-version: 3.3 + env: + BUNDLE_GEMFILE: gemfiles/active_record_71.gemfile fail-fast: false env: ${{ matrix.env }} @@ -76,7 +79,7 @@ jobs: - ruby-version: 2.7 env: BUNDLE_GEMFILE: gemfiles/active_record_52.gemfile - - ruby-version: "3.0" + - ruby-version: 3.0 env: BUNDLE_GEMFILE: gemfiles/active_record_61.gemfile - ruby-version: 3.1 @@ -85,6 +88,9 @@ jobs: - ruby-version: 3.2 env: BUNDLE_GEMFILE: gemfiles/active_record_70.gemfile + - ruby-version: 3.3 + env: + BUNDLE_GEMFILE: gemfiles/active_record_71.gemfile fail-fast: false env: ${{ matrix.env }} steps: diff --git a/Gemfile b/Gemfile index f85a943..4b1b5b3 100644 --- a/Gemfile +++ b/Gemfile @@ -2,10 +2,10 @@ source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } -gem "rails", "~> 7.0.0" +gem "rails", "~> 7.1.0" gem "pg" -gem "sqlite3" -# gem "mysql2" -gem "pry" +gem "sqlite3", "~> 1.4" +gem "mysql2" + # Specify your gem's dependencies in pagy_cursor.gemspec gemspec path: "./" diff --git a/Gemfile.lock b/Gemfile.lock index 6d68331..c49aee1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,188 +1,214 @@ PATH remote: . specs: - pagy_cursor (0.6.0) + pagy_cursor (0.7.0) activerecord (>= 5) - pagy (>= 6, < 7) + pagy (>= 6, < 9) GEM remote: https://rubygems.org/ specs: - actioncable (7.0.4.3) - actionpack (= 7.0.4.3) - activesupport (= 7.0.4.3) + actioncable (7.1.3.4) + actionpack (= 7.1.3.4) + activesupport (= 7.1.3.4) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (7.0.4.3) - actionpack (= 7.0.4.3) - activejob (= 7.0.4.3) - activerecord (= 7.0.4.3) - activestorage (= 7.0.4.3) - activesupport (= 7.0.4.3) + zeitwerk (~> 2.6) + actionmailbox (7.1.3.4) + actionpack (= 7.1.3.4) + activejob (= 7.1.3.4) + activerecord (= 7.1.3.4) + activestorage (= 7.1.3.4) + activesupport (= 7.1.3.4) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.0.4.3) - actionpack (= 7.0.4.3) - actionview (= 7.0.4.3) - activejob (= 7.0.4.3) - activesupport (= 7.0.4.3) + actionmailer (7.1.3.4) + actionpack (= 7.1.3.4) + actionview (= 7.1.3.4) + activejob (= 7.1.3.4) + activesupport (= 7.1.3.4) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp - rails-dom-testing (~> 2.0) - actionpack (7.0.4.3) - actionview (= 7.0.4.3) - activesupport (= 7.0.4.3) - rack (~> 2.0, >= 2.2.0) + rails-dom-testing (~> 2.2) + actionpack (7.1.3.4) + actionview (= 7.1.3.4) + activesupport (= 7.1.3.4) + nokogiri (>= 1.8.5) + racc + rack (>= 2.2.4) + rack-session (>= 1.0.1) rack-test (>= 0.6.3) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (7.0.4.3) - actionpack (= 7.0.4.3) - activerecord (= 7.0.4.3) - activestorage (= 7.0.4.3) - activesupport (= 7.0.4.3) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + actiontext (7.1.3.4) + actionpack (= 7.1.3.4) + activerecord (= 7.1.3.4) + activestorage (= 7.1.3.4) + activesupport (= 7.1.3.4) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.0.4.3) - activesupport (= 7.0.4.3) + actionview (7.1.3.4) + activesupport (= 7.1.3.4) builder (~> 3.1) - erubi (~> 1.4) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (7.0.4.3) - activesupport (= 7.0.4.3) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + activejob (7.1.3.4) + activesupport (= 7.1.3.4) globalid (>= 0.3.6) - activemodel (7.0.4.3) - activesupport (= 7.0.4.3) - activerecord (7.0.4.3) - activemodel (= 7.0.4.3) - activesupport (= 7.0.4.3) - activestorage (7.0.4.3) - actionpack (= 7.0.4.3) - activejob (= 7.0.4.3) - activerecord (= 7.0.4.3) - activesupport (= 7.0.4.3) + activemodel (7.1.3.4) + activesupport (= 7.1.3.4) + activerecord (7.1.3.4) + activemodel (= 7.1.3.4) + activesupport (= 7.1.3.4) + timeout (>= 0.4.0) + activestorage (7.1.3.4) + actionpack (= 7.1.3.4) + activejob (= 7.1.3.4) + activerecord (= 7.1.3.4) + activesupport (= 7.1.3.4) marcel (~> 1.0) - mini_mime (>= 1.1.0) - activesupport (7.0.4.3) + activesupport (7.1.3.4) + base64 + bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb i18n (>= 1.6, < 2) minitest (>= 5.1) + mutex_m tzinfo (~> 2.0) - builder (3.2.4) - coderay (1.1.3) - concurrent-ruby (1.2.2) + base64 (0.2.0) + bigdecimal (3.1.8) + builder (3.3.0) + concurrent-ruby (1.3.3) + connection_pool (2.4.1) crass (1.0.6) - date (3.3.3) - diff-lcs (1.5.0) - erubi (1.12.0) - globalid (1.1.0) - activesupport (>= 5.0) - i18n (1.12.0) + date (3.3.4) + diff-lcs (1.5.1) + drb (2.2.1) + erubi (1.13.0) + globalid (1.2.1) + activesupport (>= 6.1) + i18n (1.14.5) concurrent-ruby (~> 1.0) - loofah (2.20.0) + io-console (0.7.2) + irb (1.14.0) + rdoc (>= 4.0.0) + reline (>= 0.4.2) + loofah (2.22.0) crass (~> 1.0.2) - nokogiri (>= 1.5.9) + nokogiri (>= 1.12.0) mail (2.8.1) mini_mime (>= 0.1.1) net-imap net-pop net-smtp - marcel (1.0.2) - method_source (1.0.0) - mini_mime (1.1.2) - minitest (5.18.0) - net-imap (0.3.4) + marcel (1.0.4) + mini_mime (1.1.5) + minitest (5.24.1) + mutex_m (0.2.0) + mysql2 (0.5.6) + net-imap (0.4.14) date net-protocol net-pop (0.1.2) net-protocol - net-protocol (0.2.1) + net-protocol (0.2.2) timeout - net-smtp (0.3.3) + net-smtp (0.5.0) net-protocol - nio4r (2.5.9) - nokogiri (1.14.3-arm64-darwin) - racc (~> 1.4) - nokogiri (1.14.3-x86_64-darwin) + nio4r (2.7.3) + nokogiri (1.16.7-x86_64-linux) racc (~> 1.4) - pagy (6.0.3) - pg (1.4.6) - pry (0.14.2) - coderay (~> 1.1) - method_source (~> 1.0) - racc (1.6.2) - rack (2.2.6.4) + pagy (8.6.3) + pg (1.5.7) + psych (5.1.2) + stringio + racc (1.8.1) + rack (3.1.7) + rack-session (2.0.0) + rack (>= 3.0.0) rack-test (2.1.0) rack (>= 1.3) - rails (7.0.4.3) - actioncable (= 7.0.4.3) - actionmailbox (= 7.0.4.3) - actionmailer (= 7.0.4.3) - actionpack (= 7.0.4.3) - actiontext (= 7.0.4.3) - actionview (= 7.0.4.3) - activejob (= 7.0.4.3) - activemodel (= 7.0.4.3) - activerecord (= 7.0.4.3) - activestorage (= 7.0.4.3) - activesupport (= 7.0.4.3) + rackup (2.1.0) + rack (>= 3) + webrick (~> 1.8) + rails (7.1.3.4) + actioncable (= 7.1.3.4) + actionmailbox (= 7.1.3.4) + actionmailer (= 7.1.3.4) + actionpack (= 7.1.3.4) + actiontext (= 7.1.3.4) + actionview (= 7.1.3.4) + activejob (= 7.1.3.4) + activemodel (= 7.1.3.4) + activerecord (= 7.1.3.4) + activestorage (= 7.1.3.4) + activesupport (= 7.1.3.4) bundler (>= 1.15.0) - railties (= 7.0.4.3) - rails-dom-testing (2.0.3) - activesupport (>= 4.2.0) + railties (= 7.1.3.4) + rails-dom-testing (2.2.0) + activesupport (>= 5.0.0) + minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.5.0) - loofah (~> 2.19, >= 2.19.1) - railties (7.0.4.3) - actionpack (= 7.0.4.3) - activesupport (= 7.0.4.3) - method_source + rails-html-sanitizer (1.6.0) + loofah (~> 2.21) + nokogiri (~> 1.14) + railties (7.1.3.4) + actionpack (= 7.1.3.4) + activesupport (= 7.1.3.4) + irb + rackup (>= 1.0.0) rake (>= 12.2) - thor (~> 1.0) - zeitwerk (~> 2.5) - rake (13.0.6) - rspec (3.12.0) - rspec-core (~> 3.12.0) - rspec-expectations (~> 3.12.0) - rspec-mocks (~> 3.12.0) - rspec-core (3.12.2) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.3) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) + rake (13.2.1) + rdoc (6.7.0) + psych (>= 4.0.0) + reline (0.5.9) + io-console (~> 0.5) + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.0) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-mocks (3.12.5) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-support (3.12.0) - sqlite3 (1.6.2-arm64-darwin) - sqlite3 (1.6.2-x86_64-darwin) - thor (1.2.1) - timeout (0.3.2) + rspec-support (~> 3.13.0) + rspec-support (3.13.1) + sqlite3 (1.7.3-x86_64-linux) + stringio (3.1.1) + thor (1.3.1) + timeout (0.4.1) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - websocket-driver (0.7.5) + webrick (1.8.1) + websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - zeitwerk (2.6.7) + zeitwerk (2.6.17) PLATFORMS - arm64-darwin-21 - x86_64-darwin-19 + x86_64-linux DEPENDENCIES - bundler (~> 2.0) + bundler (~> 2) + mysql2 pagy_cursor! pg - pry - rails (~> 7.0.0) - rake (~> 13.0) - rspec (~> 3.0) - sqlite3 + rails (~> 7.1.0) + rake (~> 13) + rspec (~> 3) + sqlite3 (~> 1.4) BUNDLED WITH - 2.2.22 + 2.5.11 diff --git a/README.md b/README.md index 2e79cd0..dbab39e 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ Many thanks to: - [Hirokazu Hata](https://github.com/h-michael) - [M. Yunan Helmy](https://github.com/yunanhelmy) - [Eumir Gaspar](https://github.com/corroded) +- [Jasl](https://github.com/jasl) ## Support Databases diff --git a/gemfiles/active_record_71.gemfile b/gemfiles/active_record_71.gemfile new file mode 100644 index 0000000..2a23966 --- /dev/null +++ b/gemfiles/active_record_71.gemfile @@ -0,0 +1,11 @@ +source "https://rubygems.org" + +git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } + +gem "rails", "~> 7.1.0" +gem "pg" +gem "sqlite3", "~> 1.4" +gem "mysql2" + +# Specify your gem's dependencies in pagy_cursor.gemspec +gemspec path: "../" diff --git a/lib/pagy_cursor.rb b/lib/pagy_cursor.rb index 1b6743f..5963b1b 100644 --- a/lib/pagy_cursor.rb +++ b/lib/pagy_cursor.rb @@ -1,6 +1,11 @@ +# frozen_string_literal: true + require "pagy" +require "pagy_cursor/pagy/cursor" +require "pagy_cursor/pagy/extras/cursor" +require "pagy_cursor/pagy/extras/uuid_cursor" + require "pagy_cursor/version" + module PagyCursor - class Error < StandardError; end - # Your code goes here... end diff --git a/lib/pagy_cursor/pagy/cursor.rb b/lib/pagy_cursor/pagy/cursor.rb index 9367628..7829c9c 100644 --- a/lib/pagy_cursor/pagy/cursor.rb +++ b/lib/pagy_cursor/pagy/cursor.rb @@ -1,12 +1,13 @@ -class Pagy +# frozen_string_literal: true +class Pagy class Cursor < Pagy - attr_reader :before, :after, :arel_table, :primary_key, :order, :comparation, :position + attr_reader :before, :after, :arel_table, :primary_key, :order, :comparison, :position attr_accessor :has_more alias_method :has_more?, :has_more def initialize(vars) - @vars = DEFAULT.merge(vars.delete_if{|_,v| v.nil? || v == '' }) + @vars = DEFAULT.merge(vars.delete_if { |_, v| v.nil? || v == "" }) @items = vars[:items] || DEFAULT[:items] @before = vars[:before] @after = vars[:after] @@ -15,32 +16,30 @@ def initialize(vars) @reorder = vars[:order] || {} if @before.present? and @after.present? - raise(ArgumentError, 'before and after can not be both mentioned') + raise(ArgumentError, "before and after can not be both mentioned") end - if vars[:backend] == 'uuid' - - @comparation = 'lt' # arel table less than + if vars[:backend] == "uuid" + @comparison = "lt" # arel table less than @position = @before - @order = @reorder.merge({ :created_at => :desc , @primary_key => :desc }) + @order = @reorder.merge({ :created_at => :desc, @primary_key => :desc }) - if @after.present? || (@reorder.present? && @reorder.values.uniq.first.to_sym == :asc) - @comparation = 'gt' # arel table greater than + if @after.present? || (@reorder.present? && @reorder.values.uniq.first&.to_sym == :asc) + @comparison = "gt" # arel table greater than @position = @after - @order = @reorder.merge({ :created_at => :asc , @primary_key => :asc }) + @order = @reorder.merge({ :created_at => :asc, @primary_key => :asc }) end else - - @comparation = 'lt' + @comparison = "lt" @position = @before @order = @reorder.merge({ @primary_key => :desc }) - if @after.present? || (@reorder.present? && @reorder.values.uniq.first.to_sym == :asc) - @comparation = 'gt' + if @after.present? || (@reorder.present? && @reorder.values.uniq.first&.to_sym == :asc) + @comparison = "gt" @position = @after @order = @reorder.merge({ @primary_key => :asc }) end end end end - end +end diff --git a/lib/pagy_cursor/pagy/extras/cursor.rb b/lib/pagy_cursor/pagy/extras/cursor.rb index b712016..44cc625 100644 --- a/lib/pagy_cursor/pagy/extras/cursor.rb +++ b/lib/pagy_cursor/pagy/extras/cursor.rb @@ -1,29 +1,30 @@ -require 'pagy_cursor/pagy/cursor' -class Pagy - - module Backend ; private # the whole module is private so no problem with including it in a controller +# frozen_string_literal: true +class Pagy + module Backend; private # the whole module is private so no problem with including it in a controller # Return Pagy object and items - def pagy_cursor(collection, vars={}, options={}) + def pagy_cursor(collection, vars = {}) pagy = Pagy::Cursor.new(pagy_cursor_get_vars(collection, vars)) - items = pagy_cursor_get_items(collection, pagy, pagy.position) - pagy.has_more = pagy_cursor_has_more?(items, pagy) + items = pagy_cursor_get_items(collection, pagy, pagy.position) + pagy.has_more = pagy_cursor_has_more?(items, pagy) - return pagy, items + [pagy, items] end def pagy_cursor_get_vars(collection, vars) + pagy_set_items_from_params(vars) if defined?(ItemsExtra) + vars[:arel_table] = collection.arel_table vars[:primary_key] = collection.primary_key - vars[:backend] = 'sequence' + vars[:backend] = "sequence" vars end - def pagy_cursor_get_items(collection, pagy, position=nil) + def pagy_cursor_get_items(collection, pagy, position = nil) if position.present? - sql_comparation = pagy.arel_table[pagy.primary_key].send(pagy.comparation, position) - collection.where(sql_comparation).reorder(pagy.order).limit(pagy.items) + sql_comparison = pagy.arel_table[pagy.primary_key].send(pagy.comparison, position) + collection.where(sql_comparison).reorder(pagy.order).limit(pagy.items) else collection.reorder(pagy.order).limit(pagy.items) end diff --git a/lib/pagy_cursor/pagy/extras/uuid_cursor.rb b/lib/pagy_cursor/pagy/extras/uuid_cursor.rb index cfb1eff..0e23df8 100644 --- a/lib/pagy_cursor/pagy/extras/uuid_cursor.rb +++ b/lib/pagy_cursor/pagy/extras/uuid_cursor.rb @@ -1,25 +1,26 @@ -require 'pagy_cursor/pagy/cursor' -class Pagy - - module Backend ; private # the whole module is private so no problem with including it in a controller +# frozen_string_literal: true +class Pagy + module Backend; private # the whole module is private so no problem with including it in a controller # Return Pagy object and items - def pagy_uuid_cursor(collection, vars={}) + def pagy_uuid_cursor(collection, vars = {}) pagy = Pagy::Cursor.new(pagy_uuid_cursor_get_vars(collection, vars)) - items = pagy_uuid_cursor_get_items(collection, pagy, pagy.position) - pagy.has_more = pagy_uuid_cursor_has_more?(items, pagy) + items = pagy_uuid_cursor_get_items(collection, pagy, pagy.position) + pagy.has_more = pagy_uuid_cursor_has_more?(items, pagy) return pagy, items end def pagy_uuid_cursor_get_vars(collection, vars) + pagy_set_items_from_params(vars) if defined?(ItemsExtra) + vars[:arel_table] = collection.arel_table vars[:primary_key] = collection.primary_key - vars[:backend] = 'uuid' + vars[:backend] = "uuid" vars end - def pagy_uuid_cursor_get_items(collection, pagy, position=nil) + def pagy_uuid_cursor_get_items(collection, pagy, position = nil) if position.present? arel_table = pagy.arel_table @@ -28,19 +29,19 @@ def pagy_uuid_cursor_get_items(collection, pagy, position=nil) # Select the primary sort key # pagy.order should be something like: # [:created_at, :id] or [:foo_column, ..., :created_at, :id] - primary_sort_key = pagy.order.keys.detect{ |order_key| ![:created_at, :id].include?(order_key.to_sym) } || :created_at + primary_sort_key = pagy.order.keys.detect { |order_key| ![:created_at, :id].include?(order_key.to_sym) } || :created_at select_previous_row = arel_table.project(arel_table[primary_sort_key]). where(arel_table[pagy.primary_key].eq(position)) - sql_comparation = arel_table[primary_sort_key]. - send(pagy.comparation, select_previous_row). + sql_comparison = arel_table[primary_sort_key]. + send(pagy.comparison, select_previous_row). or( arel_table[primary_sort_key].eq(select_previous_row). - and(arel_table[pagy.primary_key].send(pagy.comparation, position)) + and(arel_table[pagy.primary_key].send(pagy.comparison, position)) ) - collection = collection.where(sql_comparation) + collection = collection.where(sql_comparison) end collection.reorder(pagy.order).limit(pagy.items) end diff --git a/lib/pagy_cursor/version.rb b/lib/pagy_cursor/version.rb index 594c65f..7fbfbae 100644 --- a/lib/pagy_cursor/version.rb +++ b/lib/pagy_cursor/version.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module PagyCursor - VERSION = "0.6.1" + VERSION = "0.8.0" end diff --git a/pagy_cursor.gemspec b/pagy_cursor.gemspec index 9051a98..b6bcdf7 100644 --- a/pagy_cursor.gemspec +++ b/pagy_cursor.gemspec @@ -1,4 +1,3 @@ - lib = File.expand_path("../lib", __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require "pagy_cursor/version" @@ -9,8 +8,8 @@ Gem::Specification.new do |spec| spec.authors = ["Uysim"] spec.email = ["uysimty@gmail.com"] - spec.summary = "cursor paginations for pagy" - spec.description = "use pagy for cursor paginations with rails" + spec.summary = "cursor-based pagination for pagy" + spec.description = "use pagy for cursor-based pagination with rails" spec.homepage = "https://github.com/Uysim/pagy-cursor" spec.license = "MIT" @@ -22,10 +21,10 @@ Gem::Specification.new do |spec| spec.bindir = "exe" spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] - spec.add_dependency "pagy", ">= 6", "< 7" + spec.add_dependency "pagy", ">= 6", "< 9" spec.add_dependency "activerecord", ">= 5" - spec.add_development_dependency "bundler", "~> 2.0" - spec.add_development_dependency "rake", "~> 13.0" - spec.add_development_dependency "rspec", "~> 3.0" + spec.add_development_dependency "bundler", "~> 2" + spec.add_development_dependency "rake", "~> 13" + spec.add_development_dependency "rspec", "~> 3" end diff --git a/spec/dummy/.ruby-version b/spec/dummy/.ruby-version index 94c7e90..03463f3 100644 --- a/spec/dummy/.ruby-version +++ b/spec/dummy/.ruby-version @@ -1 +1 @@ -ruby-2.6.1 \ No newline at end of file +ruby-3.3.0 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 88beef5..5234a5c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,7 +1,6 @@ ENV["RAILS_ENV"] = "test" ENV["DB"] ||= "sqlite3" -require 'rails/all' -require "rails/test_help" +require 'rails' require "pagy_cursor" require "dummy/config/environment"