From 16a4f6091a0091937b94560b8e8eca954121279b Mon Sep 17 00:00:00 2001 From: "Daniel (dB.) Doubrovkine" Date: Sat, 7 Sep 2024 08:42:35 -0400 Subject: [PATCH] Drop support for mongoid 5. --- .github/workflows/ci.yml | 2 - .rubocop_todo.yml | 3 +- CHANGELOG.md | 11 +- Gemfile | 3 - README.md | 31 +--- examples/{mongoid_scroll_feed.rb => feed.rb} | 0 examples/mongo_ruby_driver_scroll_feed.rb | 45 ----- lib/mongo/scrollable.rb | 62 ------- lib/mongoid-scroll.rb | 1 - mongoid-scroll.gemspec | 2 +- spec/mongo/collection_view_spec.rb | 186 ------------------- 11 files changed, 11 insertions(+), 335 deletions(-) rename examples/{mongoid_scroll_feed.rb => feed.rb} (100%) delete mode 100644 examples/mongo_ruby_driver_scroll_feed.rb delete mode 100644 lib/mongo/scrollable.rb delete mode 100644 spec/mongo/collection_view_spec.rb diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d7225b4..bd10658 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,8 +7,6 @@ jobs: strategy: matrix: entry: - - { ruby: '2.6', mongodb: '4.4', mongoid: '5' } - - { ruby: '3.2', mongodb: '6.0', mongoid: '5' } - { ruby: '2.7', mongodb: '4.4', mongoid: '6' } - { ruby: '2.7', mongodb: '4.4', mongoid: '7' } - { ruby: '3.0', mongodb: '4.4', mongoid: '6' } diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a6fde44..cea232b 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -51,8 +51,7 @@ Style/Documentation: Exclude: - 'spec/**/*' - 'test/**/*' - - 'examples/mongoid_scroll_feed.rb' - - 'lib/mongo/scrollable.rb' + - 'examples/feed.rb' - 'lib/mongoid/criteria/scrollable.rb' - 'lib/mongoid/scroll/base_cursor.rb' - 'lib/mongoid/scroll/cursor.rb' diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b12393..781d226 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ * [#38](https://github.com/mongoid/mongoid-scroll/pull/38): Add `previous_cursor` - [@GCorbel](https://github.com/GCorbel). * [#42](https://github.com/mongoid/mongoid-scroll/pull/42): Add `first_cursor` - [@GCorbel](https://github.com/GCorbel). * [#43](https://github.com/mongoid/mongoid-scroll/pull/43): Add `current_cursor` - [@GCorbel](https://github.com/GCorbel). +* [#44](https://github.com/mongoid/mongoid-scroll/pull/44): Drop support for Mogoid 5 and Mongo Ruby Driver - [@dblock](https://github.com/dblock). * Your contribution here. ### 1.0.1 (2023/03/15) @@ -16,8 +17,8 @@ * [#29](https://github.com/mongoid/mongoid-scroll/pull/29): Add ability to include the current record to the cursor - [@FabienChaynes](https://github.com/FabienChaynes). * [#30](https://github.com/mongoid/mongoid-scroll/pull/30): Prevent discrepancy between the original sort and the cursor sort - [@FabienChaynes](https://github.com/FabienChaynes). * [#32](https://github.com/mongoid/mongoid-scroll/pull/32): Add Base64 serialization for cursors - [@FabienChaynes](https://github.com/FabienChaynes). -* [#33](https://github.com/mongoid/mongoid-scroll/pull/33): Removed support for Mongoid 3, 4 and Moped - [@dblock](https://github.com/dblock). -* [#34](https://github.com/mongoid/mongoid-scroll/pull/34): Added support for Mongoid 8 - [@dblock](https://github.com/dblock). +* [#33](https://github.com/mongoid/mongoid-scroll/pull/33): Remove support for Mongoid 3, 4 and Moped - [@dblock](https://github.com/dblock). +* [#34](https://github.com/mongoid/mongoid-scroll/pull/34): Add support for Mongoid 8 - [@dblock](https://github.com/dblock). ### 0.3.7 (2021/06/01) @@ -32,7 +33,7 @@ ### 0.3.5 (2016/09/27) * [#11](https://github.com/mongoid/mongoid-scroll/pull/11): Compatibility with Mongoid 6 - [@dblock](https://github.com/dblock). -* [#12](https://github.com/mongoid/mongoid-scroll/pull/12): Added Danger, PR linter - [@dblock](https://github.com/dblock). +* [#12](https://github.com/mongoid/mongoid-scroll/pull/12): Add Danger, PR linter - [@dblock](https://github.com/dblock). ### 0.3.4 (2015/10/22) @@ -55,7 +56,7 @@ ### 0.3.0 (2014/1/7) * Compatibility with Mongoid 4.x - [@dblock](https://github.com/dblock). -* Implemeneted Rubocop, Ruby linter - [@dblock](https://github.com/dblock). +* Implemenet Rubocop, Ruby linter - [@dblock](https://github.com/dblock). ### 0.2.1 (2013/3/21) @@ -63,7 +64,7 @@ ### 0.2.0 (2013/3/14) -* Extended `Moped::Query` with `scroll` - [@dblock](https://github.com/dblock). +* Extend `Moped::Query` with `scroll` - [@dblock](https://github.com/dblock). * `Mongoid::Scroll::Cursor.from_record` can now be called with either a Mongoid field or `field_type` and `field_name` in the `options` hash - [@dblock](https://github.com/dblock). ### 0.1.0 (2013/2/14) diff --git a/Gemfile b/Gemfile index 27f7819..ceab4af 100644 --- a/Gemfile +++ b/Gemfile @@ -7,9 +7,6 @@ when 'HEAD' then gem 'mongoid', github: 'mongodb/mongoid' when /8/ then gem 'mongoid', '~> 8.0' when /7/ then gem 'mongoid', '~> 7.0' when /6/ then gem 'mongoid', '~> 6.0' -when /5/ then - gem 'bigdecimal', '1.3.5' - gem 'mongoid', '~> 5.0' else gem 'mongoid', version end diff --git a/README.md b/README.md index e25ac0c..a47fcb2 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ - [The Problem](#the-problem) - [Installation](#installation) - [Usage](#usage) - - [Mongoid](#mongoid) - - [Mongo-Ruby-Driver (Mongoid 5)](#mongo-ruby-driver-mongoid-5) - [Indexes and Performance](#indexes-and-performance) - [Cursors](#cursors) - [Standard Cursor](#standard-cursor) @@ -24,13 +22,13 @@ Mongoid extension that enables infinite scrolling for `Mongoid::Criteria` and `M ## Compatibility -This gem supports Mongoid 5, 6, 7 and 8. +This gem supports Mongoid 6, 7 and 8. ## Demo Check out [shows on artsy.net](http://artsy.net/shows). Keep scrolling down. -There're also two code samples for Mongoid in [examples](examples). Run `bundle exec ruby examples/mongoid_scroll_feed.rb`. +There're also two code samples for Mongoid in [examples](examples). Run `bundle exec ruby examples/feed.rb`. ## The Problem @@ -51,8 +49,6 @@ gem 'mongoid-scroll' ## Usage -### Mongoid - A sample model. ```ruby @@ -106,27 +102,6 @@ Feed::Item.desc(:position).limit(5).scroll(saved_iterator.next_cursor) do |recor end ``` -### Mongo-Ruby-Driver (Mongoid 5) - -Scroll a `Mongo::Collection::View` and save a cursor to the last item. You must also supply a `field_type` of the sort criteria. - -```ruby -saved_iterator = nil -client[:feed_items].find.sort(position: -1).limit(5).scroll(nil, { field_type: DateTime }) do |record, iterator| - # each record, one-by-one - saved_iterator = iterator -end -``` - -Resume iterating using the previously saved cursor. - -```ruby -session[:feed_items].find.sort(position: -1).limit(5).scroll(saved_iterator.next_cursor, { field_type: DateTime }) do |record, iterator| - # each record, one-by-one - saved_iterator = iterator -end -``` - ## Indexes and Performance A query without a cursor is identical to a query without a scroll. @@ -212,4 +187,4 @@ Fork the project. Make your feature addition or bug fix with tests. Send a pull MIT License, see [LICENSE](http://github.com/mongoid/mongoid-scroll/raw/master/LICENSE.md) for details. -(c) 2013-2023 [Daniel Doubrovkine](http://github.com/dblock), based on code by [Frank Macreery](http://github.com/macreery), [Artsy Inc.](http://artsy.net) +(c) 2013-2024 [Daniel Doubrovkine](http://github.com/dblock), based on code by [Frank Macreery](http://github.com/macreery), [Artsy Inc.](http://artsy.net) diff --git a/examples/mongoid_scroll_feed.rb b/examples/feed.rb similarity index 100% rename from examples/mongoid_scroll_feed.rb rename to examples/feed.rb diff --git a/examples/mongo_ruby_driver_scroll_feed.rb b/examples/mongo_ruby_driver_scroll_feed.rb deleted file mode 100644 index 2864e97..0000000 --- a/examples/mongo_ruby_driver_scroll_feed.rb +++ /dev/null @@ -1,45 +0,0 @@ -require 'bundler' -Bundler.setup(:default, :development) - -require 'mongoid-scroll' -require 'faker' - -raise 'No Mongo Ruby Driver' unless Object.const_defined?(:Mongo) - -Mongo::Logger.logger = Logger.new($stdout) -Mongo::Logger.logger.level = Logger::INFO - -Mongoid.connect_to 'mongoid_scroll_demo' -Mongoid.purge! - -# total items to insert -total_items = 20 -# a MongoDB query will be executed every scroll_by items -scroll_by = 7 - -# insert items with a position out-of-order -rands = (0..total_items).to_a.sort { rand }[0..total_items] -total_items.times do - Mongoid.default_client['feed_items'].insert_one(title: Faker::Lorem.sentence, position: rands.pop) -end - -Mongoid.default_client['feed_items'].indexes.create_one(position: 1, _id: 1) - -total_shown = 0 -next_cursor = nil -loop do - current_cursor = next_cursor - next_cursor = nil - Mongoid.default_client['feed_items'].find.limit(scroll_by).sort(position: 1).scroll(current_cursor, field_type: Integer, field_name: 'position') do |item, cursor| - puts "#{item['position']}: #{item['title']}" - next_cursor = cursor - total_shown += 1 - end - break unless next_cursor - # destroy an item just for the heck of it, scroll is not affected - item = Mongoid.default_client['feed_items'].find.sort(position: 1).first - Mongoid.default_client['feed_items'].find(_id: item['_id']).delete_one -end - -# this will be 20 -puts "Shown #{total_shown} items." diff --git a/lib/mongo/scrollable.rb b/lib/mongo/scrollable.rb deleted file mode 100644 index a6bed88..0000000 --- a/lib/mongo/scrollable.rb +++ /dev/null @@ -1,62 +0,0 @@ -module Mongo - module Scrollable - include Mongoid::Criteria::Scrollable::Fields - include Mongoid::Criteria::Scrollable::Cursors - - def scroll(cursor_or_type = nil, options = nil, &_block) - cursor, cursor_type = cursor_and_type(cursor_or_type) - view = self - # we don't support scrolling over a view with multiple fields - raise Mongoid::Scroll::Errors::MultipleSortFieldsError.new(sort: view.sort) if view.sort && view.sort.keys.size != 1 - # scroll field and direction - scroll_field = view.sort ? view.sort.keys.first : :_id - scroll_direction = view.sort ? view.sort.values.first.to_i : 1 - # scroll cursor from the parameter, with value and tiebreak_id - options = { field_type: BSON::ObjectId } unless options - cursor_options = { field_name: scroll_field, direction: scroll_direction }.merge(options) - cursor = cursor && cursor.is_a?(cursor_type) ? cursor : cursor_type.new(cursor, cursor_options) - raise_mismatched_sort_fields_error!(cursor, cursor_options) if different_sort_fields?(cursor, cursor_options) - - records = nil - if cursor.type == :previous - # scroll backwards by reversing the sort order, limit and then reverse again - pipeline = [ - { '$match' => view.selector.merge(cursor.criteria) }, - { '$sort' => { scroll_field => -scroll_direction } }, - { '$limit' => limit }, - { '$sort' => { scroll_field => scroll_direction } } - ] - aggregation_options = view.options.except(:sort) - records = view.aggregate(pipeline, aggregation_options) - else - # make a view - records = Mongo::Collection::View.new( - view.collection, - view.selector.merge(cursor.criteria), - sort: (view.sort || {}).merge(_id: scroll_direction), - skip: skip, - limit: limit - ) - end - # 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), - current_cursor: current_cursor - ) - yield record, iterator - end - else - records - end - end - end -end - -Mongo::Collection::View.send(:include, Mongo::Scrollable) diff --git a/lib/mongoid-scroll.rb b/lib/mongoid-scroll.rb index 7671ab2..cca74c0 100644 --- a/lib/mongoid-scroll.rb +++ b/lib/mongoid-scroll.rb @@ -12,5 +12,4 @@ require 'mongoid/criteria/scrollable/fields' require 'mongoid/criteria/scrollable/cursors' require 'mongoid/criteria/scrollable/iterator' -require 'mongo/scrollable' if Object.const_defined?(:Mongo) require 'mongoid/criteria/scrollable' diff --git a/mongoid-scroll.gemspec b/mongoid-scroll.gemspec index df81317..f1ae2a3 100644 --- a/mongoid-scroll.gemspec +++ b/mongoid-scroll.gemspec @@ -13,7 +13,7 @@ Gem::Specification.new do |s| s.homepage = 'http://github.com/mongoid/mongoid-scroll' s.licenses = ['MIT'] s.summary = 'Mongoid extensions to enable infinite scroll.' - s.add_dependency 'mongoid', '>= 3.0' + s.add_dependency 'mongoid', '>= 6.0' s.add_dependency 'mongoid-compatibility' s.add_dependency 'i18n' end diff --git a/spec/mongo/collection_view_spec.rb b/spec/mongo/collection_view_spec.rb deleted file mode 100644 index 6144a42..0000000 --- a/spec/mongo/collection_view_spec.rb +++ /dev/null @@ -1,186 +0,0 @@ -require 'spec_helper' - -if Object.const_defined?(:Mongo) - describe Mongo::Collection::View do - [Mongoid::Scroll::Cursor, Mongoid::Scroll::Base64EncodedCursor].each do |cursor_type| - context cursor_type do - context 'scrollable' do - subject do - Mongoid.default_client['feed_items'].find - end - it ':scroll' do - expect(subject).to respond_to(:scroll) - end - end - context 'with multiple sort fields' do - subject do - Mongoid.default_client['feed_items'].find.sort(name: 1, value: -1) - end - it 'raises Mongoid::Scroll::Errors::MultipleSortFieldsError' do - expect { subject.scroll(cursor_type) }.to raise_error Mongoid::Scroll::Errors::MultipleSortFieldsError, - /You're attempting to scroll over data with a sort order that includes multiple fields: name, value./ - end - end - context 'with different sort fields between the cursor and the criteria' do - subject do - Mongoid.default_client['feed_items'].find.sort(name: -1) - end - - it 'raises Mongoid::Scroll::Errors::MismatchedSortFieldsError' do - record = Feed::Item.create! - cursor = cursor_type.from_record(record, field: record.fields['a_string']) - expect(cursor).to be_a cursor_type - error_string = /You're attempting to scroll over data with a sort order that differs between the cursor and the original criteria: field_name, direction./ - expect { subject.scroll(cursor, field_type: String) }.to raise_error Mongoid::Scroll::Errors::MismatchedSortFieldsError, error_string - end - end - context 'with no sort' do - subject do - Mongoid.default_client['feed_items'].find - end - it 'adds a default sort by _id' do - expect(subject.scroll(cursor_type).sort).to eq('_id' => 1) - end - end - context 'with data' do - before :each do - 10.times do |i| - Mongoid.default_client['feed_items'].insert_one( - a_string: i.to_s, - a_integer: i, - a_datetime: DateTime.mongoize(DateTime.new(2013, i + 1, 21, 1, 42, 3, 'UTC')), - a_date: Date.mongoize(Date.new(2013, i + 1, 21)), - a_time: Time.mongoize(Time.at(Time.now.to_i + i)) - ) - end - end - context 'default' do - it 'scrolls all' do - records = [] - Mongoid.default_client['feed_items'].find.scroll(cursor_type) do |record, iterator| - records << record - end - expect(records.size).to eq 10 - expect(records).to eq Mongoid.default_client['feed_items'].find.to_a - end - end - { a_string: String, a_integer: Integer, a_date: Date, a_datetime: DateTime }.each_pair do |field_name, field_type| - context field_type do - it 'scrolls all with a block' do - records = [] - Mongoid.default_client['feed_items'].find.sort(field_name => 1).scroll(cursor_type, field_type: field_type) do |record, iterator| - records << record - end - expect(records.size).to eq 10 - expect(records).to eq Mongoid.default_client['feed_items'].find.to_a - end - it 'scrolls all with a break' do - records = [] - cursor = nil - Mongoid.default_client['feed_items'].find.sort(field_name => 1).limit(5).scroll(cursor_type, field_type: field_type) do |record, iterator| - records << record - cursor = iterator.next_cursor - expect(cursor).to be_a cursor_type - end - expect(records.size).to eq 5 - Mongoid.default_client['feed_items'].find.sort(field_name => 1).scroll(cursor, field_type: field_type) do |record, iterator| - records << record - cursor = iterator.next_cursor - expect(cursor).to be_a cursor_type - end - expect(records.size).to eq 10 - expect(records).to eq Mongoid.default_client['feed_items'].find.to_a - end - it 'scrolls in descending order' do - records = [] - Mongoid.default_client['feed_items'].find.sort(field_name => -1).limit(3).scroll(cursor_type, field_type: field_type, field_name: field_name) do |record, iterator| - records << record - end - expect(records.size).to eq 3 - expect(records).to eq Mongoid.default_client['feed_items'].find.sort(field_name => -1).limit(3).to_a - end - it 'map' do - record = Mongoid.default_client['feed_items'].find.limit(3).scroll(cursor_type, field_type: field_type, field_name: field_name).map { |r| r }.last - cursor = cursor_type.from_record(record, field_type: field_type, field_name: field_name) - expect(cursor).to_not be nil - expect(cursor.value).to eq record[field_name.to_s] - expect(cursor.tiebreak_id).to eq record['_id'] - end - it 'can scroll back with the previous cursor' do - first_iterator = nil - second_iterator = nil - third_iterator = nil - - Mongoid.default_client['feed_items'].find.sort(field_name => 1).limit(2).scroll(cursor_type, field_type: field_type) do |_, iterator| - first_iterator = iterator - end - - Mongoid.default_client['feed_items'].find.sort(field_name => 1).limit(2).scroll(first_iterator.next_cursor, field_type: field_type) do |_, iterator| - second_iterator = iterator - end - - Mongoid.default_client['feed_items'].find.sort(field_name => 1).limit(2).scroll(second_iterator.next_cursor, field_type: field_type) do |_, iterator| - third_iterator = iterator - end - - records = Mongoid.default_client['feed_items'].find.sort(field_name => 1) - 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 - it 'can loop over the first records with the first cursor' do - first_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 |_, iterator| - first_cursor = iterator.first_cursor - end - - expect(records.limit(2).scroll(first_cursor, field_type: field_type).to_a).to eq(records.limit(2).to_a) - end - end - end - end - context 'with overlapping data', if: MongoDB.mmapv1? do - before :each do - 3.times { Feed::Item.create! a_integer: 5 } - Feed::Item.first.update_attributes!(name: Array(1000).join('a')) - end - it 'natural order is different from order by id' do - # natural order isn't necessarily going to be the same as _id order - # if a document is updated and grows in size, it may need to be relocated and - # thus cause the natural order to change - expect(Feed::Item.order_by('$natural' => 1).to_a).to_not eq Feed::Item.order_by(_id: 1).to_a - end - [{ a_integer: 1 }, { a_integer: -1 }].each do |sort_order| - it "scrolls by #{sort_order}" do - records = [] - cursor = nil - Mongoid.default_client['feed_items'].find.sort(sort_order).limit(2).scroll(cursor_type) do |record, iterator| - records << record - cursor = iterator.next_cursor - end - expect(records.size).to eq 2 - Mongoid.default_client['feed_items'].find.sort(sort_order).scroll(cursor) do |record, iterator| - records << record - end - expect(records.size).to eq 3 - expect(records).to eq Mongoid.default_client['feed_items'].find.sort(sort_order.merge(_id: sort_order[:a_integer])).to_a - end - end - end - end - end - end -end