• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

drecom / activerecord-turntable / #1372

31 Aug 2023 03:28AM UTC coverage: 87.281% (-1.3%) from 88.629%
#1372

push

web-flow
Merge pull request #20 from mixigroup/fix-ci-matrix

Change CI matrix, Not support Ruby 2.4 in Rails6.

2587 of 2964 relevant lines covered (87.28%)

389.95 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

55.56
/lib/active_record/turntable/active_record_ext/locking_optimistic.rb
1
module ActiveRecord::Turntable
1✔
2
  module ActiveRecordExt
1✔
3
    module LockingOptimistic
1✔
4
      if Util.ar_version_equals_or_later?("5.1.6")
1✔
5
        ::ActiveRecord::Locking::Optimistic.class_eval <<-EOD
1✔
6
          private
7

8
          def _update_row(attribute_names, attempted_action = "update")
9
            return super unless locking_enabled?
10

11
            begin
12
              locking_column = self.class.locking_column
13
              previous_lock_value = read_attribute_before_type_cast(locking_column)
14
              attribute_names << locking_column
15

16
              self[locking_column] += 1
17

18
              constraints = {
19
                self.class.primary_key => id_in_database,
20
                locking_column => previous_lock_value
21
              }
22
              if self.class.sharding_condition_needed?
23
                constraints[self.class.turntable_shard_key] = self[self.class.turntable_shard_key]
24
              end
25

26
              if Util.ar52_or_later?
27
                affected_rows = self.class._update_record(
28
                  attributes_with_values(attribute_names),
29
                  constraints,
30
                )
31
              else
32
                affected_rows = self.class.unscoped._update_record(
33
                  arel_attributes_with_values(attribute_names),
34
                  constraints,
35
                )
36
              end
37

38
              if affected_rows != 1
39
                raise ActiveRecord::StaleObjectError.new(self, attempted_action)
40
              end
41

42
              affected_rows
43

44
            # If something went wrong, revert the locking_column value.
45
            rescue Exception
46
              self[locking_column] = previous_lock_value.to_i
47
              raise
48
            end
49
          end
50
        EOD
51
      elsif Util.ar51?
×
52
        ::ActiveRecord::Locking::Optimistic.class_eval <<-EOD
×
53
          private
54
          # @note Override to add sharding condition on optimistic locking
55
          def _update_record(attribute_names = self.attribute_names)
56
            return super unless locking_enabled?
57
            return 0 if attribute_names.empty?
58

59
            begin
60
              klass = self.class
61

62
              lock_col = self.class.locking_column
63

64
              previous_lock_value = read_attribute_before_type_cast(lock_col)
65

66
              increment_lock
67

68
              attribute_names.push(lock_col)
69

70
              relation = self.class.unscoped
71

72
              condition_scope = relation.where(
73
                self.class.primary_key => id,
74
                lock_col => previous_lock_value
75
              )
76
              if klass.turntable_enabled? and klass.primary_key != klass.turntable_shard_key.to_s
77
                condition_scope = condition_scope.where(
78
                  klass.turntable_shard_key => self.send(klass.turntable_shard_key)
79
                )
80
              end
81

82
              affected_rows = condition_scope.update_all(
83
                attributes_for_update(attribute_names).map do |name|
84
                  [name, _read_attribute(name)]
85
                end.to_h
86
              )
87

88
              unless affected_rows == 1
89
                raise ActiveRecord::StaleObjectError.new(self, "update")
90
              end
91

92
              affected_rows
93

94
            # If something went wrong, revert the locking_column value.
95
            rescue Exception
96
              send(lock_col + "=", previous_lock_value.to_i)
97
              raise
98
            end
99
          end
100
        EOD
101
      elsif Util.earlier_than_ar51?
×
102
        ::ActiveRecord::Locking::Optimistic.class_eval <<-EOD
×
103
          private
104
          # @note Override to add sharding condition on optimistic locking
105
          def _update_record(attribute_names = self.attribute_names) #:nodoc:
106
            return super unless locking_enabled?
107
            return 0 if attribute_names.empty?
108

109
            klass = self.class
110
            lock_col = self.class.locking_column
111
            previous_lock_value = send(lock_col).to_i
112
            increment_lock
113

114
            attribute_names += [lock_col]
115
            attribute_names.uniq!
116

117
            begin
118
              relation = self.class.unscoped
119

120
              condition_scope = relation.where(
121
                self.class.primary_key => id,
122
                lock_col => previous_lock_value,
123
              )
124
              if klass.turntable_enabled? and klass.primary_key != klass.turntable_shard_key.to_s
125
                condition_scope = condition_scope.where(
126
                  klass.turntable_shard_key => self.send(klass.turntable_shard_key)
127
                )
128
              end
129

130
              affected_rows = condition_scope.update_all(
131
                attributes_for_update(attribute_names).map do |name|
132
                  [name, _read_attribute(name)]
133
                end.to_h
134
              )
135

136
              unless affected_rows == 1
137
                raise ActiveRecord::StaleObjectError.new(self, "update")
138
              end
139

140
              affected_rows
141

142
              # If something went wrong, revert the version.
143
            rescue Exception
144
              send(lock_col + '=', previous_lock_value)
145
              raise
146
            end
147
          end
148
        EOD
149
      end
150
    end
151
  end
152
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc