diff --git a/CHANGELOG b/CHANGELOG index 83fbb5bd9..5f74794cc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,7 +6,7 @@ * Stop using a transaction for a single query if calling Dataset#import with a dataset (jeremyevans) -* Add paged_update_delete plugin for paged deletes and updates (jeremyevans) (#2080) +* Add paged_operations plugin for paged deletes and updates and other custom operations (jeremyevans) (#2080) * Support to_tsquery: :websearch option to Dataset#full_text_search on PostgreSQL 11+ (jeremyevans) (#2075) diff --git a/lib/sequel/plugins/paged_update_delete.rb b/lib/sequel/plugins/paged_operations.rb similarity index 85% rename from lib/sequel/plugins/paged_update_delete.rb rename to lib/sequel/plugins/paged_operations.rb index aab4347f9..46c12051b 100644 --- a/lib/sequel/plugins/paged_update_delete.rb +++ b/lib/sequel/plugins/paged_operations.rb @@ -2,7 +2,7 @@ module Sequel module Plugins - # The paged_update_delete plugin adds +paged_update+ and + # The paged_operations plugin adds +paged_update+ and # +paged_delete+ dataset methods. These behave similarly to # the default +update+ and +delete+ dataset methods, except # that the update or deletion is done in potentially multiple @@ -39,9 +39,9 @@ module Plugins # # To set the number of rows to be updated or deleted per query # by +paged_update+ or +paged_delete+, you can use the - # +paged_update_delete_size+ dataset method: + # +paged_operations_size+ dataset method: # - # Album.where{name <= 'M'}.paged_update_delete_size(3). + # Album.where{name <= 'M'}.paged_operations_size(3). # paged_update(:updated_at=>Sequel::CURRENT_TIMESTAMP) # # SELECT id FROM albums WHERE (name <= 'M') ORDER BY id LIMIT 1 OFFSET 4 # # UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE ((name <= 'M') AND ("id" < 5)) @@ -74,26 +74,26 @@ module Plugins # # # Make all model subclasses support paged update/delete # # (called before loading subclasses) - # Sequel::Model.plugin :paged_update_delete + # Sequel::Model.plugin :paged_operations # # # Make the Album class support paged update/delete - # Album.plugin :paged_update_delete - module PagedUpdateDelete + # Album.plugin :paged_operations + module PagedOperations module ClassMethods - Plugins.def_dataset_methods(self, [:paged_datasets, :paged_delete, :paged_update, :paged_update_delete_size]) + Plugins.def_dataset_methods(self, [:paged_datasets, :paged_delete, :paged_update, :paged_operations_size]) end module DatasetMethods # Yield datasets for subsets of the receiver that are limited # to no more than 1000 rows (you can configure the number of - # rows using paged_update_delete_size). + # rows using paged_operations_size). def paged_datasets unless defined?(yield) return enum_for(:paged_datasets) end - pk = _paged_update_delete_pk(:paged_update) - base_offset_ds = offset_ds = _paged_update_delete_offset_ds + pk = _paged_operations_pk(:paged_update) + base_offset_ds = offset_ds = _paged_operations_offset_ds first = nil while last = offset_ds.get(pk) @@ -112,11 +112,11 @@ def paged_datasets # Delete all rows of the dataset using using multiple queries so that # no more than 1000 rows are deleted at a time (you can configure the - # number of rows using paged_update_delete_size). + # number of rows using paged_operations_size). def paged_delete - pk = _paged_update_delete_pk(:paged_delete) + pk = _paged_operations_pk(:paged_delete) rows_deleted = 0 - offset_ds = _paged_update_delete_offset_ds + offset_ds = _paged_operations_offset_ds while last = offset_ds.get(pk) rows_deleted += where(pk < last).delete end @@ -125,7 +125,7 @@ def paged_delete # Update all rows of the dataset using using multiple queries so that # no more than 1000 rows are updated at a time (you can configure the - # number of rows using paged_update_delete_size). All arguments are + # number of rows using paged_operations_size). All arguments are # passed to Dataset#update. def paged_update(*args) rows_updated = 0 @@ -137,16 +137,16 @@ def paged_update(*args) # Set the number of rows to update or delete per query when using # paged_update or paged_delete. - def paged_update_delete_size(rows) - raise Error, "paged_update_delete_size rows must be greater than 0" unless rows >= 1 - clone(:paged_updated_delete_rows=>rows) + def paged_operations_size(rows) + raise Error, "paged_operations_size rows must be greater than 0" unless rows >= 1 + clone(:paged_operations_rows=>rows) end private # Run some basic checks before running paged UPDATE or DELETE queries, # and return the primary key to operate on as a Sequel::Identifier. - def _paged_update_delete_pk(meth) + def _paged_operations_pk(meth) raise Error, "cannot use #{meth} if dataset has a limit or offset" if @opts[:limit] || @opts[:offset] case pk = model.primary_key @@ -161,8 +161,8 @@ def _paged_update_delete_pk(meth) # The dataset that will be used by paged_update and paged_delete # to get the upper limit for the next UPDATE or DELETE query. - def _paged_update_delete_offset_ds - offset = @opts[:paged_updated_delete_rows] || 1000 + def _paged_operations_offset_ds + offset = @opts[:paged_operations_rows] || 1000 _force_primary_key_order.offset(offset) end end diff --git a/spec/extensions/paged_update_delete_spec.rb b/spec/extensions/paged_operations_spec.rb similarity index 91% rename from spec/extensions/paged_update_delete_spec.rb rename to spec/extensions/paged_operations_spec.rb index cd1784af0..19e605c71 100644 --- a/spec/extensions/paged_update_delete_spec.rb +++ b/spec/extensions/paged_operations_spec.rb @@ -1,10 +1,10 @@ require_relative "spec_helper" -describe "paged_update_delete plugin" do +describe "paged_operations plugin" do before do @db = Sequel.mock @c = Class.new(Sequel::Model(@db[:albums])) - @c.plugin :paged_update_delete + @c.plugin :paged_operations @ds = @c.dataset @db.sqls @db.fetch = [[{:id=>1002}], [{:id=>2002}]] @@ -129,9 +129,9 @@ ] end - it "#paged_update_delete_size should set the page size for paged_update" do + it "#paged_operations_size should set the page size for paged_update" do @db.numrows = [4, 4, 2] - @ds.paged_update_delete_size(4).paged_delete.must_equal 10 + @ds.paged_operations_size(4).paged_delete.must_equal 10 @db.sqls.must_equal [ "SELECT id FROM albums ORDER BY id LIMIT 1 OFFSET 4", "DELETE FROM albums WHERE (id < 1002)", @@ -142,9 +142,9 @@ ] end - it "#paged_update_delete_size should set the page size for paged_delete" do + it "#paged_operations_size should set the page size for paged_delete" do @db.numrows = [4, 4, 2] - @ds.paged_update_delete_size(4).paged_update(:x=>1).must_equal 10 + @ds.paged_operations_size(4).paged_update(:x=>1).must_equal 10 @db.sqls.must_equal [ "SELECT id FROM albums ORDER BY id LIMIT 1 OFFSET 4", "UPDATE albums SET x = 1 WHERE (id < 1002)", @@ -155,9 +155,9 @@ ] end - it "#paged_update_delete_size should set the page size for paged_datasets" do + it "#paged_operations_size should set the page size for paged_datasets" do @db.numrows = [4, 4, 2] - @ds.paged_update_delete_size(4).paged_datasets.map(&:sql).must_equal [ + @ds.paged_operations_size(4).paged_datasets.map(&:sql).must_equal [ "SELECT * FROM albums WHERE (id < 1002)", "SELECT * FROM albums WHERE ((id < 2002) AND (id >= 1002))", "SELECT * FROM albums WHERE (id >= 2002)" @@ -168,9 +168,9 @@ "SELECT id FROM albums WHERE (id >= 2002) ORDER BY id LIMIT 1 OFFSET 4", ] end - it "should raise error for invalid size passed to paged_update_delete_size" do - proc{@ds.paged_update_delete_size(0)}.must_raise Sequel::Error - proc{@ds.paged_update_delete_size(-1)}.must_raise Sequel::Error + it "should raise error for invalid size passed to paged_operations_size" do + proc{@ds.paged_operations_size(0)}.must_raise Sequel::Error + proc{@ds.paged_operations_size(-1)}.must_raise Sequel::Error end it "should raise error for dataset with limit" do @@ -236,9 +236,9 @@ ] end - it "should offer paged_update_delete_size class method" do + it "should offer paged_operations_size class method" do @db.numrows = [4, 4, 2] - @c.paged_update_delete_size(4).paged_delete.must_equal 10 + @c.paged_operations_size(4).paged_delete.must_equal 10 @db.sqls.must_equal [ "SELECT id FROM albums ORDER BY id LIMIT 1 OFFSET 4", "DELETE FROM albums WHERE (id < 1002)", diff --git a/spec/integration/plugin_test.rb b/spec/integration/plugin_test.rb index 8ce5d8bbf..135aea741 100644 --- a/spec/integration/plugin_test.rb +++ b/spec/integration/plugin_test.rb @@ -3017,7 +3017,7 @@ def set(k, v, ttl) self[k] = v end end if DB.database_type == :postgres end if RUBY_VERSION >= '2.3' && (begin; require 'sequel/plugins/column_encryption'; true; rescue LoadError; false end) -describe "paged_update_delete plugin" do +describe "paged_operations plugin" do before(:all) do @db = DB @db.create_table!(:pud_test) do @@ -3026,7 +3026,7 @@ def set(k, v, ttl) self[k] = v end end @model = Class.new(Sequel::Model) @model.set_dataset @db[:pud_test] - @model.plugin :paged_update_delete + @model.plugin :paged_operations @sizes = [1, 2, 3, 10, 11, 98, 99, 100, 101] end before do @@ -3042,7 +3042,7 @@ def set(k, v, ttl) self[k] = v end it "Model#paged_delete should work on unfiltered dataset" do @sizes.each do |rows| @db.transaction(:rollback=>:always) do - @model.paged_update_delete_size(rows).paged_delete.must_equal 100 + @model.paged_operations_size(rows).paged_delete.must_equal 100 @model.count.must_equal 0 end end @@ -3054,7 +3054,7 @@ def set(k, v, ttl) self[k] = v end expected = 100.times.map{|i| [i+1, i+200]} @sizes.each do |rows| @db.transaction(:rollback=>:always) do - @model.paged_update_delete_size(rows).paged_update(:o=>Sequel[:o] + 200).must_equal 100 + @model.paged_operations_size(rows).paged_update(:o=>Sequel[:o] + 200).must_equal 100 @model.select_order_map([:id, :o]).must_equal expected end end @@ -3067,7 +3067,7 @@ def set(k, v, ttl) self[k] = v end @sizes.zip(final_counts).each do |rows, expected_fc| @db.transaction(:rollback=>:always) do counts = [] - @model.paged_update_delete_size(rows).paged_datasets{|ds| counts << ds.count} + @model.paged_operations_size(rows).paged_datasets{|ds| counts << ds.count} counts.pop.must_equal expected_fc counts.each{|c| c.must_equal rows} end @@ -3081,7 +3081,7 @@ def set(k, v, ttl) self[k] = v end ds = @model.where{id < 50} @sizes.each do |rows| @db.transaction(:rollback=>:always) do - ds.paged_update_delete_size(rows).paged_delete.must_equal 49 + ds.paged_operations_size(rows).paged_delete.must_equal 49 ds.count.must_equal 0 @model.count.must_equal 51 end @@ -3098,7 +3098,7 @@ def set(k, v, ttl) self[k] = v end other_expected = 51.times.map{|i| [i+50, i+49]} @sizes.each do |rows| @db.transaction(:rollback=>:always) do - ds.paged_update_delete_size(rows).paged_update(:o=>Sequel[:o] + 200).must_equal 49 + ds.paged_operations_size(rows).paged_update(:o=>Sequel[:o] + 200).must_equal 49 ds.select_order_map([:id, :o]).must_equal ds_expected other.select_order_map([:id, :o]).must_equal other_expected end @@ -3114,7 +3114,7 @@ def set(k, v, ttl) self[k] = v end @sizes.zip(final_counts).each do |rows, expected_fc| @db.transaction(:rollback=>:always) do counts = [] - ds.paged_update_delete_size(rows).paged_datasets{|ds| counts << ds.count} + ds.paged_operations_size(rows).paged_datasets{|ds| counts << ds.count} counts.pop.must_equal expected_fc counts.each{|c| c.must_equal rows} end diff --git a/www/pages/plugins.html.erb b/www/pages/plugins.html.erb index 90c74139e..7a49771b2 100644 --- a/www/pages/plugins.html.erb +++ b/www/pages/plugins.html.erb @@ -463,8 +463,8 @@ Allows Sequel::Model classes to implement PostgreSQL row-valued/composite types.
  • -paged_update_delete -Allows updating and deleting a large dataset using multiple queries to reduce the amount of time the table is locked. +paged_operations +Allows operating across a large dataset using multiple queries to reduce the amount of time the table is locked.
  • primary_key_lookup_check_values