File: run_transaction_hooks.rb

package info (click to toggle)
ruby-sequel 5.63.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 10,408 kB
  • sloc: ruby: 113,747; makefile: 3
file content (72 lines) | stat: -rw-r--r-- 2,037 bytes parent folder | download | duplicates (3)
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# frozen-string-literal: true
#
# The run_transaction_hooks extension allows for running after_commit or
# after_rollback extensions before commit or rollback.  It then removes
# the hook after running it, so it will not be run twice.
#
# This extension should only be used in transactional tests where the
# transaction always rolls back, to test the behavior of the after_commit
# and after_rollback hooks.  Any other usage is probably a bad idea.
#
# Example:
#
#   DB.extension :run_transaction_hooks
#   x = 1
#   DB.transaction(rollback: :always) do
#     DB.after_rollback{x = 3}
#     DB.after_commit{x = 2}
#
#     x # => 1
#     DB.run_after_rollback_hooks
#     x # => 3
#     DB.run_after_commit_hooks
#     x # => 2
#   end
#   x # => 2

#
class Sequel::Database
  module RunTransactionHooks
    # Run all savepoint and transaction after_commit hooks for the current transaction,
    # and remove the hooks after running them.
    # Options:
    # :server :: The server/shard to use.
    def run_after_commit_hooks(opts=OPTS)
      _run_transaction_hooks(:after_commit, opts)
    end

    # Run all savepoint and transaction after_rollback hooks for the current transaction,
    # and remove the hooks after running them.
    # Options:
    # :server :: The server/shard to use.
    def run_after_rollback_hooks(opts=OPTS)
      _run_transaction_hooks(:after_rollback, opts)
    end

    private

    def _run_transaction_hooks(type, opts)
      synchronize(opts[:server]) do |conn|
        unless h = _trans(conn)
          raise Sequel::Error, "Cannot call run_#{type}_hooks outside of a transaction"
        end

        if hooks = h[type]
          hooks.each(&:call)
          hooks.clear
        end

        if (savepoints = h[:savepoints])
          savepoints.each do |savepoint|
            if hooks = savepoint[type]
              hooks.each(&:call)
              hooks.clear
            end
          end
        end
      end
    end
  end

  register_extension(:run_transaction_hooks, RunTransactionHooks)
end