File: single_statement_dataset_destroy.rb

package info (click to toggle)
ruby-sequel 5.101.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 11,312 kB
  • sloc: ruby: 124,594; makefile: 3
file content (49 lines) | stat: -rw-r--r-- 1,786 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# frozen-string-literal: true

module Sequel
  module Plugins
    # The single_statement_dataset_destroy plugin makes the
    # model dataset.destroy method delete all rows in a
    # single DELETE statement. It runs all before_destroy
    # hooks before the DELETE, and all after_destroy hooks
    # after the delete.
    #
    # This is not compatible with around_destroy hooks,
    # so if the model is using custom around_destroy hooks,
    # dataset.destroy falls back to a separate DELETE statement
    # per row.
    #
    # Usage:
    #
    #   # Make all model subclasses use a single DELETE
    #   # statement for dataset.destroy
    #   Sequel::Model.plugin :single_statement_dataset_destroy
    #
    #   # Make the Album class use a single DELETE
    #   # statement for dataset.destroy
    #   Album.plugin :single_statement_dataset_destroy
    module SingleStatementDatasetDestroy
      module DatasetMethods
        # Destroy all rows in a single DELETE statement. Run the before_destroy
        # hooks for all rows before the DELETE, and all after_destroy hooks
        # for all rows after the DELETE. If the model uses an around_destroy
        # hook, fallback to using a separate DELETE statement per row.
        def destroy
          return super unless model.instance_method(:around_destroy).owner == Sequel::Model::InstanceMethods

          db.transaction do
            rows = all
            rows.each(&:before_destroy)
            expected_rows = rows.length
            n = delete
            unless n == expected_rows
              raise Error, "dataset changed during destroy, expected rows: #{expected_rows}, actual rows: #{n}"
            end
            rows.each(&:after_destroy)
            n
          end
        end
      end
    end
  end
end