From 4e3ad8044f33d49b44f80c17d346ac6968bff1fc Mon Sep 17 00:00:00 2001 From: GCorbel Date: Tue, 3 Sep 2024 16:30:42 -0400 Subject: [PATCH 1/9] Add a cursor for the current page. --- lib/mongoid/criteria/scrollable.rb | 5 ++++- lib/mongoid/criteria/scrollable/iterator.rb | 5 +++-- spec/mongoid/criteria_spec.rb | 10 ++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/mongoid/criteria/scrollable.rb b/lib/mongoid/criteria/scrollable.rb index 3e89327..724074c 100644 --- a/lib/mongoid/criteria/scrollable.rb +++ b/lib/mongoid/criteria/scrollable.rb @@ -15,11 +15,14 @@ def scroll(cursor_or_type = nil, &_block) records = find_records(criteria, cursor) if block_given? previous_cursor = nil + current_cursor = nil records.each do |record| previous_cursor ||= cursor_from_record(cursor_type, record, cursor_options.merge(type: :previous)) + current_cursor ||= cursor_from_record(cursor_type, record, cursor_options.merge(include_current: true)) iterator = Mongoid::Criteria::Scrollable::Iterator.new( previous_cursor: previous_cursor, - next_cursor: cursor_from_record(cursor_type, record, cursor_options) + next_cursor: cursor_from_record(cursor_type, record, cursor_options), + current_cursor: current_cursor ) yield record, iterator end diff --git a/lib/mongoid/criteria/scrollable/iterator.rb b/lib/mongoid/criteria/scrollable/iterator.rb index fb11b91..0f98db8 100644 --- a/lib/mongoid/criteria/scrollable/iterator.rb +++ b/lib/mongoid/criteria/scrollable/iterator.rb @@ -2,10 +2,11 @@ module Mongoid class Criteria module Scrollable class Iterator - attr_accessor :previous_cursor, :next_cursor + attr_accessor :previous_cursor, :current_cursor, :next_cursor - def initialize(previous_cursor:, next_cursor:) + def initialize(previous_cursor:, current_cursor:, next_cursor:) @previous_cursor = previous_cursor + @current_cursor = current_cursor @next_cursor = next_cursor end end diff --git a/spec/mongoid/criteria_spec.rb b/spec/mongoid/criteria_spec.rb index 26e5cd4..3711e9b 100644 --- a/spec/mongoid/criteria_spec.rb +++ b/spec/mongoid/criteria_spec.rb @@ -181,6 +181,16 @@ expect(Feed::Item.asc(field_name).limit(2).scroll(second_iterator.previous_cursor)).to eq(records.limit(2)) expect(Feed::Item.asc(field_name).limit(2).scroll(third_iterator.previous_cursor)).to eq(records.skip(2).limit(2)) end + it 'can loop over the first records with the first page cursor' do + current_cursor = nil + cursor = cursor_type.from_record Feed::Item.find_by(name: '7'), field_name: field_name, field_type: field_type + + Feed::Item.asc(field_name).limit(2).scroll(cursor) do |record, iterator| + current_cursor = iterator.current_cursor + end + + expect(Feed::Item.asc(field_name).limit(2).scroll(current_cursor).to_a).to eq(Feed::Item.asc(field_name).last(2)) + end end end end From ec3ddaa88eda9a093962e20f14b4c5e66cb6757d Mon Sep 17 00:00:00 2001 From: GCorbel Date: Tue, 3 Sep 2024 16:36:49 -0400 Subject: [PATCH 2/9] add a line in CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94006e5..9d62af4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ### 2.0.0 (Next) * [#38](https://github.com/mongoid/mongoid-scroll/pull/38): Allow to reverse the scroll - [@GCorbel](https://github.com/GCorbel). +* [#43](https://github.com/mongoid/mongoid-scroll/pull/43): Add a cursor to go to the first page - [@GCorbel](https://github.com/GCorbel). * Your contribution here. ### 1.0.1 (2023/03/15) From d88c9cdcbc9336b2ae0e30ca84222bdb4f7cb88d Mon Sep 17 00:00:00 2001 From: GCorbel Date: Tue, 3 Sep 2024 16:37:54 -0400 Subject: [PATCH 3/9] fix Changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d62af4..202811a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ### 2.0.0 (Next) * [#38](https://github.com/mongoid/mongoid-scroll/pull/38): Allow to reverse the scroll - [@GCorbel](https://github.com/GCorbel). -* [#43](https://github.com/mongoid/mongoid-scroll/pull/43): Add a cursor to go to the first page - [@GCorbel](https://github.com/GCorbel). +* [#43](https://github.com/mongoid/mongoid-scroll/pull/43): Add a cursor to go to the current page - [@GCorbel](https://github.com/GCorbel). * Your contribution here. ### 1.0.1 (2023/03/15) From 951902ff9f7f800cf19677312bb8c9718eae69ef Mon Sep 17 00:00:00 2001 From: GCorbel Date: Tue, 3 Sep 2024 17:05:27 -0400 Subject: [PATCH 4/9] add for mongo view --- lib/mongo/scrollable.rb | 5 ++++- spec/mongo/collection_view_spec.rb | 11 +++++++++++ spec/mongoid/criteria_spec.rb | 4 ++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/mongo/scrollable.rb b/lib/mongo/scrollable.rb index 1f40b59..726e337 100644 --- a/lib/mongo/scrollable.rb +++ b/lib/mongo/scrollable.rb @@ -41,11 +41,14 @@ def scroll(cursor_or_type = nil, options = nil, &_block) # scroll if block_given? previous_cursor = nil + current_cursor = nil records.each do |record| previous_cursor ||= cursor_type.from_record(record, cursor_options.merge(type: :previous)) + current_cursor ||= cursor_type.from_record(record, cursor_options.merge(include_current: true)) iterator = Mongoid::Criteria::Scrollable::Iterator.new( previous_cursor: previous_cursor, - next_cursor: cursor_type.from_record(record, cursor_options) + next_cursor: cursor_type.from_record(record, cursor_options), + current_cursor: current_cursor ) yield record, iterator end diff --git a/spec/mongo/collection_view_spec.rb b/spec/mongo/collection_view_spec.rb index 2f329e3..8c8a3e0 100644 --- a/spec/mongo/collection_view_spec.rb +++ b/spec/mongo/collection_view_spec.rb @@ -127,6 +127,17 @@ expect(Mongoid.default_client['feed_items'].find.sort(field_name => 1).limit(2).scroll(second_iterator.previous_cursor, field_type: field_type).to_a).to eq(records.limit(2).to_a) expect(Mongoid.default_client['feed_items'].find.sort(field_name => 1).limit(2).scroll(third_iterator.previous_cursor, field_type: field_type).to_a).to eq(records.skip(2).limit(2).to_a) end + it 'can loop over the same records with the current cursor' do + current_cursor = nil + records = Mongoid.default_client['feed_items'].find.sort(field_name => 1) + cursor = cursor_type.from_record records.skip(4).first, field_name: field_name, field_type: field_type, include_current: true + + records.limit(2).scroll(cursor, field_type: field_type) do |record, iterator| + current_cursor = iterator.current_cursor + end + + expect(records.limit(2).scroll(current_cursor, field_type: field_type).to_a).to eq(records.skip(4).limit(2).to_a) + end end end end diff --git a/spec/mongoid/criteria_spec.rb b/spec/mongoid/criteria_spec.rb index 3711e9b..f474923 100644 --- a/spec/mongoid/criteria_spec.rb +++ b/spec/mongoid/criteria_spec.rb @@ -181,11 +181,11 @@ expect(Feed::Item.asc(field_name).limit(2).scroll(second_iterator.previous_cursor)).to eq(records.limit(2)) expect(Feed::Item.asc(field_name).limit(2).scroll(third_iterator.previous_cursor)).to eq(records.skip(2).limit(2)) end - it 'can loop over the first records with the first page cursor' do + it 'can loop over the same records with the current cursor' do current_cursor = nil cursor = cursor_type.from_record Feed::Item.find_by(name: '7'), field_name: field_name, field_type: field_type - Feed::Item.asc(field_name).limit(2).scroll(cursor) do |record, iterator| + Feed::Item.asc(field_name).limit(2).scroll(cursor) do |_, iterator| current_cursor = iterator.current_cursor end From 39ba36fd60a4fda83bf2f87743a17c5f056cbd70 Mon Sep 17 00:00:00 2001 From: Guirec Corbel Date: Wed, 4 Sep 2024 09:03:26 -0400 Subject: [PATCH 5/9] Update CHANGELOG.md Co-authored-by: Daniel (dB.) Doubrovkine --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 202811a..3e3406f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ### 2.0.0 (Next) * [#38](https://github.com/mongoid/mongoid-scroll/pull/38): Allow to reverse the scroll - [@GCorbel](https://github.com/GCorbel). -* [#43](https://github.com/mongoid/mongoid-scroll/pull/43): Add a cursor to go to the current page - [@GCorbel](https://github.com/GCorbel). +* [#43](https://github.com/mongoid/mongoid-scroll/pull/43): Add a current cursor - [@GCorbel](https://github.com/GCorbel). * Your contribution here. ### 1.0.1 (2023/03/15) From 8d6d607bcbdfaebffb978572caf34dcff3c87519 Mon Sep 17 00:00:00 2001 From: GCorbel Date: Wed, 4 Sep 2024 09:17:09 -0400 Subject: [PATCH 6/9] minor change --- README.md | 2 ++ lib/mongo/scrollable.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6657577..c3faa32 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,8 @@ Feed::Item.desc(:position).limit(5).scroll(saved_iterator.previous_cursor) do |r end ``` +`saved_iterator.current_cursor` can be used to loop over the same records again. + The iteration finishes when no more records are available. You can also finish iterating over the remaining records by omitting the query limit. ```ruby diff --git a/lib/mongo/scrollable.rb b/lib/mongo/scrollable.rb index 726e337..a6bed88 100644 --- a/lib/mongo/scrollable.rb +++ b/lib/mongo/scrollable.rb @@ -48,7 +48,7 @@ def scroll(cursor_or_type = nil, options = nil, &_block) iterator = Mongoid::Criteria::Scrollable::Iterator.new( previous_cursor: previous_cursor, next_cursor: cursor_type.from_record(record, cursor_options), - current_cursor: current_cursor + current_cursor: current_cursor ) yield record, iterator end From fa743d9cad25aae9676e91cfd6de13acd4eafac4 Mon Sep 17 00:00:00 2001 From: GCorbel Date: Wed, 4 Sep 2024 10:04:29 -0400 Subject: [PATCH 7/9] try to fix specs on CI --- spec/mongoid/criteria_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/mongoid/criteria_spec.rb b/spec/mongoid/criteria_spec.rb index f474923..23b8605 100644 --- a/spec/mongoid/criteria_spec.rb +++ b/spec/mongoid/criteria_spec.rb @@ -183,13 +183,13 @@ end it 'can loop over the same records with the current cursor' do current_cursor = nil - cursor = cursor_type.from_record Feed::Item.find_by(name: '7'), field_name: field_name, field_type: field_type + cursor = cursor_type.from_record Feed::Item.skip(4).first, field_name: field_name, field_type: field_type, include_current: true Feed::Item.asc(field_name).limit(2).scroll(cursor) do |_, iterator| current_cursor = iterator.current_cursor end - expect(Feed::Item.asc(field_name).limit(2).scroll(current_cursor).to_a).to eq(Feed::Item.asc(field_name).last(2)) + expect(Feed::Item.asc(field_name).limit(2).scroll(current_cursor).to_a).to eq(Feed::Item.asc(field_name).skip(4).limit(2).to_a) end end end From 6262836ccf4817a84286904f80f2140d523fdb90 Mon Sep 17 00:00:00 2001 From: Guirec Corbel Date: Wed, 4 Sep 2024 10:05:36 -0400 Subject: [PATCH 8/9] Update README.md Co-authored-by: Daniel (dB.) Doubrovkine --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c3faa32..ee1a798 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ Feed::Item.desc(:position).limit(5).scroll(saved_iterator.previous_cursor) do |r end ``` -`saved_iterator.current_cursor` can be used to loop over the same records again. +Use `saved_iterator.current_cursor` to loop over the same records again. The iteration finishes when no more records are available. You can also finish iterating over the remaining records by omitting the query limit. From 14be59af65109aa4d9282d8aeb97915e0cc1c8a2 Mon Sep 17 00:00:00 2001 From: GCorbel Date: Wed, 4 Sep 2024 17:08:53 -0400 Subject: [PATCH 9/9] remove extra spaces in the README --- README.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/README.md b/README.md index 2a3a0f8..e25ac0c 100644 --- a/README.md +++ b/README.md @@ -161,14 +161,7 @@ end ## Cursors -You can use `Mongoid::Scroll::Cursor.from_record` to generate a cursor. A cursor points at the last record of the - - - - - - -iteration and unlike MongoDB cursors will not expire. +You can use `Mongoid::Scroll::Cursor.from_record` to generate a cursor. A cursor points at the last record of the iteration and unlike MongoDB cursors will not expire. ```ruby record = Feed::Item.desc(:position).limit(3).last