activerecord-turntable 3.0.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +3 -1
- data/CHANGELOG.md +10 -0
- data/Gemfile +2 -2
- data/Rakefile +5 -3
- data/gemfiles/rails5_1_0.gemfile +7 -0
- data/gemfiles/rails5_1_1.gemfile +7 -0
- data/lib/active_record/turntable.rb +1 -0
- data/lib/active_record/turntable/active_record_ext/abstract_adapter.rb +32 -3
- data/lib/active_record/turntable/active_record_ext/connection_handler_extension.rb +3 -1
- data/lib/active_record/turntable/active_record_ext/fixtures.rb +29 -0
- data/lib/active_record/turntable/active_record_ext/locking_optimistic.rb +92 -40
- data/lib/active_record/turntable/active_record_ext/persistence.rb +18 -4
- data/lib/active_record/turntable/active_record_ext/query_cache.rb +36 -16
- data/lib/active_record/turntable/active_record_ext/schema_dumper.rb +6 -3
- data/lib/active_record/turntable/active_record_ext/transactions.rb +23 -28
- data/lib/active_record/turntable/compatibility.rb +44 -0
- data/lib/active_record/turntable/util.rb +7 -2
- data/lib/active_record/turntable/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 66d31edc8c786999ddb71e35bf5f64e3dd97978a
|
|
4
|
+
data.tar.gz: 5cad32e83086caff4e7fdb1ad8c89e0393286c3e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5ec384d210033d0f2831b9db8381d422a913d8d2d736ecb1422b8870ee12624ff1f0eaadf46b13c3191e2c0f5d28bf6b8fef9ea9c83deaa54866e680ccd8d441
|
|
7
|
+
data.tar.gz: 67c6d75b06df8ea9b3c5014d43454f3ec4ef7411123ce76b93fff053e37a2caf60ded5eea3f9eff31bc3d2e5f503514226ef82cc1180e0a01e812df05f3fe075
|
data/.travis.yml
CHANGED
|
@@ -15,6 +15,8 @@ gemfile:
|
|
|
15
15
|
- gemfiles/rails5_0_1.gemfile
|
|
16
16
|
- gemfiles/rails5_0_2.gemfile
|
|
17
17
|
- gemfiles/rails5_0_3.gemfile
|
|
18
|
+
- gemfiles/rails5_1_0.gemfile
|
|
19
|
+
- gemfiles/rails5_1_1.gemfile
|
|
18
20
|
- gemfiles/rails_edge.gemfile
|
|
19
21
|
|
|
20
22
|
env:
|
|
@@ -40,7 +42,7 @@ matrix:
|
|
|
40
42
|
- rvm: 2.4.1
|
|
41
43
|
gemfile: gemfiles/rails_edge.gemfile
|
|
42
44
|
- rvm: 2.3.4
|
|
43
|
-
gemfile: gemfiles/
|
|
45
|
+
gemfile: gemfiles/rails5_1_1.gemfile
|
|
44
46
|
allow_failures:
|
|
45
47
|
- rvm: ruby-head
|
|
46
48
|
- gemfile: gemfiles/rails_edge.gemfile
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## activerecord-turntable 3.1.0 ##
|
|
2
|
+
|
|
3
|
+
### Major Changes
|
|
4
|
+
|
|
5
|
+
* Support activerecord v5.1.x
|
|
6
|
+
|
|
7
|
+
### Bugfix
|
|
8
|
+
|
|
9
|
+
* Fix schema dumper to dump sequence table options correctly (activerecord >= 5.0.1)
|
|
10
|
+
|
|
1
11
|
## activerecord-turntable 3.0.1 ##
|
|
2
12
|
|
|
3
13
|
### Minor Changes
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
|
@@ -48,7 +48,7 @@ namespace :turntable do
|
|
|
48
48
|
configurations.each do |configuration|
|
|
49
49
|
ActiveRecord::Base.establish_connection configuration
|
|
50
50
|
|
|
51
|
-
ActiveRecord::Base.connection.create_table :users do |t|
|
|
51
|
+
ActiveRecord::Base.connection.create_table :users, comment: "comment" do |t|
|
|
52
52
|
t.string :nickname
|
|
53
53
|
t.string :thumbnail_url
|
|
54
54
|
t.binary :blob
|
|
@@ -56,7 +56,7 @@ namespace :turntable do
|
|
|
56
56
|
t.datetime :deleted_at
|
|
57
57
|
t.timestamps
|
|
58
58
|
end
|
|
59
|
-
ActiveRecord::Base.connection.create_sequence_for :users
|
|
59
|
+
ActiveRecord::Base.connection.create_sequence_for :users, comment: "comment"
|
|
60
60
|
|
|
61
61
|
ActiveRecord::Base.connection.create_table :user_statuses do |t|
|
|
62
62
|
t.belongs_to :user, :null => false
|
|
@@ -129,7 +129,8 @@ namespace :turntable do
|
|
|
129
129
|
namespace :activerecord do
|
|
130
130
|
task(:env) do
|
|
131
131
|
ENV["ARCONFIG"] ||= File.expand_path("spec/config/activerecord_config.yml", __dir__)
|
|
132
|
-
ENV["ARVERSION"] ||= if ActiveRecord.gem_version.prerelease?
|
|
132
|
+
ENV["ARVERSION"] ||= if ActiveRecord.gem_version.prerelease? &&
|
|
133
|
+
!ActiveRecord.gem_version.segments.include?("rc")
|
|
133
134
|
"origin/master"
|
|
134
135
|
else
|
|
135
136
|
"v#{ActiveRecord.gem_version}"
|
|
@@ -143,6 +144,7 @@ namespace :turntable do
|
|
|
143
144
|
Dir.chdir("tmp/rails") do
|
|
144
145
|
system(*%W|git checkout #{ENV['ARVERSION']}|)
|
|
145
146
|
end
|
|
147
|
+
FileUtils.rm_r("test") if File.directory?("test")
|
|
146
148
|
FileUtils.cp_r("tmp/rails/activerecord/test", ".")
|
|
147
149
|
FileUtils.cp_r("tmp/rails/activerecord/Rakefile", "activerecord.rake")
|
|
148
150
|
File.open("test/cases/helper.rb", "a") do |f|
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
module ActiveRecord::Turntable
|
|
2
2
|
module ActiveRecordExt
|
|
3
3
|
module AbstractAdapter
|
|
4
|
+
extend Compatibility
|
|
5
|
+
|
|
6
|
+
def self.prepended(klass)
|
|
7
|
+
klass.prepend(self.compatible_module)
|
|
8
|
+
klass.class_eval { protected :log }
|
|
9
|
+
end
|
|
10
|
+
|
|
4
11
|
def translate_exception_class(e, sql)
|
|
5
12
|
begin
|
|
6
13
|
message = "#{e.class.name}: #{e.message}: #{sql} : #{turntable_shard_name}"
|
|
@@ -12,11 +19,32 @@ module ActiveRecord::Turntable
|
|
|
12
19
|
exception.set_backtrace e.backtrace
|
|
13
20
|
exception
|
|
14
21
|
end
|
|
22
|
+
protected :translate_exception_class
|
|
15
23
|
|
|
16
24
|
# @note override for append current shard name
|
|
17
25
|
# rubocop:disable Style/HashSyntax, Style/MultilineMethodCallBraceLayout
|
|
18
|
-
|
|
26
|
+
module V5_1
|
|
19
27
|
def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil)
|
|
28
|
+
@instrumenter.instrument(
|
|
29
|
+
"sql.active_record",
|
|
30
|
+
sql: sql,
|
|
31
|
+
name: name,
|
|
32
|
+
binds: binds,
|
|
33
|
+
type_casted_binds: type_casted_binds,
|
|
34
|
+
statement_name: statement_name,
|
|
35
|
+
connection_id: object_id,
|
|
36
|
+
turntable_shard_name: turntable_shard_name) do
|
|
37
|
+
@lock.synchronize do
|
|
38
|
+
yield
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
rescue => e
|
|
42
|
+
raise translate_exception_class(e, sql)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
module V5_0_3
|
|
47
|
+
def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil) # :doc:
|
|
20
48
|
@instrumenter.instrument(
|
|
21
49
|
"sql.active_record",
|
|
22
50
|
sql: sql,
|
|
@@ -29,7 +57,9 @@ module ActiveRecord::Turntable
|
|
|
29
57
|
rescue => e
|
|
30
58
|
raise translate_exception_class(e, sql)
|
|
31
59
|
end
|
|
32
|
-
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
module V5_0
|
|
33
63
|
def log(sql, name = "SQL", binds = [], statement_name = nil)
|
|
34
64
|
@instrumenter.instrument(
|
|
35
65
|
"sql.active_record",
|
|
@@ -45,7 +75,6 @@ module ActiveRecord::Turntable
|
|
|
45
75
|
end
|
|
46
76
|
# rubocop:enable Style/HashSyntax, Style/MultilineMethodCallBraceLayout
|
|
47
77
|
|
|
48
|
-
protected :translate_exception_class, :log
|
|
49
78
|
|
|
50
79
|
def turntable_shard_name=(name)
|
|
51
80
|
@turntable_shard_name = name.to_s
|
|
@@ -11,7 +11,9 @@ module ActiveRecord::Turntable
|
|
|
11
11
|
# A connection was established in an ancestor process that must have
|
|
12
12
|
# subsequently forked. We can't reuse the connection, but we can copy
|
|
13
13
|
# the specification and establish a new connection with it.
|
|
14
|
-
|
|
14
|
+
spec = ancestor_pool.spec
|
|
15
|
+
spec = spec.to_hash if spec.respond_to?(:to_hash)
|
|
16
|
+
establish_connection(spec).tap do |pool|
|
|
15
17
|
pool.schema_cache = ancestor_pool.schema_cache if ancestor_pool.schema_cache
|
|
16
18
|
end
|
|
17
19
|
else
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
# force TestFixtures to begin transaction with all shards.
|
|
3
3
|
#
|
|
4
4
|
require "active_record/fixtures"
|
|
5
|
+
require "active_record/turntable/util"
|
|
5
6
|
|
|
6
7
|
module ActiveRecord
|
|
7
8
|
class FixtureSet
|
|
@@ -79,6 +80,7 @@ module ActiveRecord
|
|
|
79
80
|
@fixture_cache = {}
|
|
80
81
|
@fixture_connections = []
|
|
81
82
|
@@already_loaded_fixtures ||= {}
|
|
83
|
+
@connection_subscriber = nil
|
|
82
84
|
|
|
83
85
|
# Load fixtures once and begin transaction.
|
|
84
86
|
if run_in_transaction?
|
|
@@ -88,11 +90,38 @@ module ActiveRecord
|
|
|
88
90
|
@loaded_fixtures = load_fixtures(config)
|
|
89
91
|
@@already_loaded_fixtures[self.class] = @loaded_fixtures
|
|
90
92
|
end
|
|
93
|
+
|
|
94
|
+
# Begin transactions for connections already established
|
|
91
95
|
ActiveRecord::Base.force_connect_all_shards!
|
|
92
96
|
@fixture_connections = enlist_fixture_connections
|
|
93
97
|
@fixture_connections.each do |connection|
|
|
94
98
|
connection.begin_transaction joinable: false
|
|
99
|
+
if ActiveRecord::Turntable::Util.ar51_or_later?
|
|
100
|
+
connection.pool.lock_thread = true
|
|
101
|
+
end
|
|
95
102
|
end
|
|
103
|
+
|
|
104
|
+
if ActiveRecord::Turntable::Util.ar51_or_later?
|
|
105
|
+
# When connections are established in the future, begin a transaction too
|
|
106
|
+
@connection_subscriber = ActiveSupport::Notifications.subscribe("!connection.active_record") do |_, _, _, _, payload|
|
|
107
|
+
spec_name = payload[:spec_name] if payload.key?(:spec_name)
|
|
108
|
+
|
|
109
|
+
if spec_name
|
|
110
|
+
begin
|
|
111
|
+
connection = ActiveRecord::Base.connection_handler.retrieve_connection(spec_name)
|
|
112
|
+
rescue ConnectionNotEstablished
|
|
113
|
+
connection = nil
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
if connection && !@fixture_connections.include?(connection)
|
|
117
|
+
connection.begin_transaction joinable: false
|
|
118
|
+
connection.pool.lock_thread = true
|
|
119
|
+
@fixture_connections << connection
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
96
125
|
# Load fixtures for every test.
|
|
97
126
|
else
|
|
98
127
|
ActiveRecord::FixtureSet.reset_cache
|
|
@@ -1,53 +1,105 @@
|
|
|
1
1
|
module ActiveRecord::Turntable
|
|
2
2
|
module ActiveRecordExt
|
|
3
3
|
module LockingOptimistic
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
self.class.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
klass.turntable_shard_key => self.send(klass.turntable_shard_key)
|
|
4
|
+
if Util.ar51_or_later?
|
|
5
|
+
::ActiveRecord::Locking::Optimistic.class_eval <<-EOD
|
|
6
|
+
private
|
|
7
|
+
# @note Override to add sharding condition on optimistic locking
|
|
8
|
+
def _update_record(attribute_names = self.attribute_names)
|
|
9
|
+
return super unless locking_enabled?
|
|
10
|
+
return 0 if attribute_names.empty?
|
|
11
|
+
|
|
12
|
+
begin
|
|
13
|
+
klass = self.class
|
|
14
|
+
|
|
15
|
+
lock_col = self.class.locking_column
|
|
16
|
+
|
|
17
|
+
previous_lock_value = read_attribute_before_type_cast(lock_col)
|
|
18
|
+
|
|
19
|
+
increment_lock
|
|
20
|
+
|
|
21
|
+
attribute_names.push(lock_col)
|
|
22
|
+
|
|
23
|
+
relation = self.class.unscoped
|
|
24
|
+
|
|
25
|
+
condition_scope = relation.where(
|
|
26
|
+
self.class.primary_key => id,
|
|
27
|
+
lock_col => previous_lock_value
|
|
29
28
|
)
|
|
30
|
-
|
|
29
|
+
if klass.turntable_enabled? and klass.primary_key != klass.turntable_shard_key.to_s
|
|
30
|
+
condition_scope = condition_scope.where(
|
|
31
|
+
klass.turntable_shard_key => self.send(klass.turntable_shard_key)
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
affected_rows = condition_scope.update_all(
|
|
36
|
+
attributes_for_update(attribute_names).map do |name|
|
|
37
|
+
[name, _read_attribute(name)]
|
|
38
|
+
end.to_h
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
unless affected_rows == 1
|
|
42
|
+
raise ActiveRecord::StaleObjectError.new(self, "update")
|
|
43
|
+
end
|
|
31
44
|
|
|
32
|
-
|
|
33
|
-
attributes_for_update(attribute_names).map do |name|
|
|
34
|
-
[name, _read_attribute(name)]
|
|
35
|
-
end.to_h
|
|
36
|
-
)
|
|
45
|
+
affected_rows
|
|
37
46
|
|
|
38
|
-
|
|
39
|
-
|
|
47
|
+
# If something went wrong, revert the locking_column value.
|
|
48
|
+
rescue Exception
|
|
49
|
+
send(lock_col + "=", previous_lock_value.to_i)
|
|
50
|
+
raise
|
|
40
51
|
end
|
|
52
|
+
end
|
|
53
|
+
EOD
|
|
54
|
+
else
|
|
55
|
+
::ActiveRecord::Locking::Optimistic.class_eval <<-EOD
|
|
56
|
+
private
|
|
57
|
+
# @note Override to add sharding condition on optimistic locking
|
|
58
|
+
def _update_record(attribute_names = self.attribute_names) #:nodoc:
|
|
59
|
+
return super unless locking_enabled?
|
|
60
|
+
return 0 if attribute_names.empty?
|
|
61
|
+
|
|
62
|
+
klass = self.class
|
|
63
|
+
lock_col = self.class.locking_column
|
|
64
|
+
previous_lock_value = send(lock_col).to_i
|
|
65
|
+
increment_lock
|
|
66
|
+
|
|
67
|
+
attribute_names += [lock_col]
|
|
68
|
+
attribute_names.uniq!
|
|
69
|
+
|
|
70
|
+
begin
|
|
71
|
+
relation = self.class.unscoped
|
|
72
|
+
|
|
73
|
+
condition_scope = relation.where(
|
|
74
|
+
self.class.primary_key => id,
|
|
75
|
+
lock_col => previous_lock_value,
|
|
76
|
+
)
|
|
77
|
+
if klass.turntable_enabled? and klass.primary_key != klass.turntable_shard_key.to_s
|
|
78
|
+
condition_scope = condition_scope.where(
|
|
79
|
+
klass.turntable_shard_key => self.send(klass.turntable_shard_key)
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
affected_rows = condition_scope.update_all(
|
|
84
|
+
attributes_for_update(attribute_names).map do |name|
|
|
85
|
+
[name, _read_attribute(name)]
|
|
86
|
+
end.to_h
|
|
87
|
+
)
|
|
41
88
|
|
|
42
|
-
|
|
89
|
+
unless affected_rows == 1
|
|
90
|
+
raise ActiveRecord::StaleObjectError.new(self, "update")
|
|
91
|
+
end
|
|
43
92
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
93
|
+
affected_rows
|
|
94
|
+
|
|
95
|
+
# If something went wrong, revert the version.
|
|
96
|
+
rescue Exception
|
|
97
|
+
send(lock_col + '=', previous_lock_value)
|
|
98
|
+
raise
|
|
99
|
+
end
|
|
48
100
|
end
|
|
49
|
-
|
|
50
|
-
|
|
101
|
+
EOD
|
|
102
|
+
end
|
|
51
103
|
end
|
|
52
104
|
end
|
|
53
105
|
end
|
|
@@ -29,7 +29,12 @@ module ActiveRecord::Turntable
|
|
|
29
29
|
# @note Override to add sharding scope on `touch`
|
|
30
30
|
# rubocop:disable Style/UnlessElse
|
|
31
31
|
def touch(*names, time: nil)
|
|
32
|
-
|
|
32
|
+
unless persisted?
|
|
33
|
+
raise ActiveRecord::ActiveRecordError, <<-MSG.squish
|
|
34
|
+
cannot touch on a new or destroyed record object. Consider using
|
|
35
|
+
persisted?, new_record?, or destroyed? before touching
|
|
36
|
+
MSG
|
|
37
|
+
end
|
|
33
38
|
|
|
34
39
|
time ||= current_time_from_proper_timezone
|
|
35
40
|
attributes = timestamp_attributes_for_update_in_model
|
|
@@ -43,7 +48,7 @@ module ActiveRecord::Turntable
|
|
|
43
48
|
changes[column] = write_attribute(column, time)
|
|
44
49
|
end
|
|
45
50
|
|
|
46
|
-
clear_attribute_changes(changes.keys)
|
|
51
|
+
clear_attribute_changes(changes.keys) unless Util.ar51_or_later?
|
|
47
52
|
primary_key = self.class.primary_key
|
|
48
53
|
scope = if turntable_enabled? && primary_key != self.class.turntable_shard_key.to_s
|
|
49
54
|
self.class.unscoped.where(self.class.turntable_shard_key => _read_attribute(turntable_shard_key))
|
|
@@ -58,12 +63,14 @@ module ActiveRecord::Turntable
|
|
|
58
63
|
changes[locking_column] = increment_lock
|
|
59
64
|
end
|
|
60
65
|
|
|
66
|
+
clear_attribute_changes(changes.keys) if Util.ar51_or_later?
|
|
61
67
|
result = scope.update_all(changes) == 1
|
|
62
68
|
|
|
63
69
|
if !result && locking_enabled?
|
|
64
70
|
raise ActiveRecord::StaleObjectError.new(self, "touch")
|
|
65
71
|
end
|
|
66
72
|
|
|
73
|
+
@_trigger_update_callback = result
|
|
67
74
|
result
|
|
68
75
|
else
|
|
69
76
|
true
|
|
@@ -113,13 +120,20 @@ module ActiveRecord::Turntable
|
|
|
113
120
|
klass = self.class
|
|
114
121
|
attributes_values = arel_attributes_with_values_for_update(attribute_names)
|
|
115
122
|
if attributes_values.empty?
|
|
116
|
-
0
|
|
123
|
+
rows_affected = 0
|
|
124
|
+
@_trigger_update_callback = true
|
|
117
125
|
else
|
|
118
126
|
scope = if klass.turntable_enabled? && (klass.primary_key != klass.turntable_shard_key.to_s)
|
|
119
127
|
klass.unscoped.where(klass.turntable_shard_key => self.send(turntable_shard_key))
|
|
120
128
|
end
|
|
121
|
-
|
|
129
|
+
previous_id = Util.ar51_or_later? ? id_in_database : id_was
|
|
130
|
+
rows_affected = klass.unscoped._update_record attributes_values, id, previous_id, scope
|
|
131
|
+
@_trigger_update_callback = rows_affected > 0
|
|
122
132
|
end
|
|
133
|
+
|
|
134
|
+
yield(self) if block_given?
|
|
135
|
+
|
|
136
|
+
rows_affected
|
|
123
137
|
end
|
|
124
138
|
end
|
|
125
139
|
end
|
|
@@ -3,40 +3,36 @@ module ActiveRecord::Turntable
|
|
|
3
3
|
module QueryCache
|
|
4
4
|
def self.prepended(klass)
|
|
5
5
|
class << klass
|
|
6
|
-
|
|
7
|
-
prepend(ClassMethods::AR5_0_1)
|
|
8
|
-
else
|
|
9
|
-
prepend(ClassMethods::AR5_0)
|
|
10
|
-
end
|
|
6
|
+
prepend ClassMethods.compatible_module
|
|
11
7
|
end
|
|
12
8
|
end
|
|
13
9
|
|
|
14
10
|
module ClassMethods
|
|
15
|
-
|
|
11
|
+
extend Compatibility
|
|
12
|
+
|
|
13
|
+
module V5_1
|
|
16
14
|
def run
|
|
17
15
|
result = super
|
|
18
16
|
|
|
19
17
|
pools = ActiveRecord::Base.turntable_connections.values
|
|
20
|
-
pools.each do |
|
|
21
|
-
|
|
18
|
+
pools.each do |pool|
|
|
19
|
+
pool.enable_query_cache!
|
|
22
20
|
end
|
|
23
21
|
|
|
24
|
-
result
|
|
22
|
+
[*result, pools]
|
|
25
23
|
end
|
|
26
24
|
|
|
27
25
|
def complete(state)
|
|
28
|
-
|
|
29
|
-
super
|
|
26
|
+
caching_pool, caching_was_enabled, turntable_pools = state
|
|
27
|
+
super([caching_pool, caching_was_enabled])
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
k.connection.clear_query_cache
|
|
34
|
-
k.connection.disable_query_cache! unless enabled
|
|
29
|
+
turntable_pools.each do |pool|
|
|
30
|
+
pool.disable_query_cache! unless caching_was_enabled
|
|
35
31
|
end
|
|
36
32
|
end
|
|
37
33
|
end
|
|
38
34
|
|
|
39
|
-
module
|
|
35
|
+
module V5_0_1
|
|
40
36
|
def run
|
|
41
37
|
result = super
|
|
42
38
|
|
|
@@ -57,6 +53,30 @@ module ActiveRecord::Turntable
|
|
|
57
53
|
end
|
|
58
54
|
end
|
|
59
55
|
end
|
|
56
|
+
|
|
57
|
+
module V5_0
|
|
58
|
+
def run
|
|
59
|
+
result = super
|
|
60
|
+
|
|
61
|
+
pools = ActiveRecord::Base.turntable_connections.values
|
|
62
|
+
pools.each do |k|
|
|
63
|
+
k.connection.enable_query_cache!
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
result
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def complete(state)
|
|
70
|
+
enabled, _connection_id = state
|
|
71
|
+
super
|
|
72
|
+
|
|
73
|
+
klasses = ActiveRecord::Base.turntable_connections.values
|
|
74
|
+
klasses.each do |k|
|
|
75
|
+
k.connection.clear_query_cache
|
|
76
|
+
k.connection.disable_query_cache! unless enabled
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
60
80
|
end
|
|
61
81
|
|
|
62
82
|
def self.install_turntable_executor_hooks(executor = ActiveSupport::Executor)
|
|
@@ -20,11 +20,14 @@ module ActiveRecord::Turntable
|
|
|
20
20
|
|
|
21
21
|
table_options = @connection.table_options(table)
|
|
22
22
|
if table_options.present?
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
if respond_to?(:format_options, true)
|
|
24
|
+
tbl.print ", #{format_options(table_options)}"
|
|
25
|
+
else
|
|
26
|
+
tbl.print ", options: #{table_options.inspect}"
|
|
27
|
+
end
|
|
25
28
|
end
|
|
26
29
|
|
|
27
|
-
if comment = @connection.table_comment(table).presence
|
|
30
|
+
if Util.ar_version_earlier_than?("5.0.1") && comment = @connection.table_comment(table).presence
|
|
28
31
|
tbl.print ", comment: #{comment.inspect}"
|
|
29
32
|
end
|
|
30
33
|
tbl.puts
|
|
@@ -3,28 +3,25 @@ module ActiveRecord::Turntable
|
|
|
3
3
|
module Transactions
|
|
4
4
|
# @note Override to start transaction on current shard
|
|
5
5
|
def with_transaction_returning_status
|
|
6
|
-
|
|
7
|
-
status = nil
|
|
8
|
-
if self.new_record? && self.turntable_shard_key.to_s == self.class.primary_key &&
|
|
9
|
-
self.id.nil? && self.class.connection.prefetch_primary_key?(self.class.table_name)
|
|
10
|
-
self.id = self.class.connection.next_sequence_value(self.class.sequence_name)
|
|
11
|
-
end
|
|
12
|
-
self.class.connection.shards_transaction([self.turntable_shard]) do
|
|
13
|
-
add_to_transaction
|
|
14
|
-
begin
|
|
15
|
-
status = yield
|
|
16
|
-
rescue ActiveRecord::Rollback
|
|
17
|
-
clear_transaction_record_state
|
|
18
|
-
status = nil
|
|
19
|
-
end
|
|
6
|
+
return super unless self.class.turntable_enabled?
|
|
20
7
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
super
|
|
8
|
+
status = nil
|
|
9
|
+
if self.new_record? && self.turntable_shard_key.to_s == self.class.primary_key &&
|
|
10
|
+
self.id.nil? && self.class.connection.prefetch_primary_key?(self.class.table_name)
|
|
11
|
+
self.id = self.class.connection.next_sequence_value(self.class.sequence_name)
|
|
26
12
|
end
|
|
13
|
+
self.class.connection.shards_transaction([self.turntable_shard]) do
|
|
14
|
+
add_to_transaction
|
|
15
|
+
begin
|
|
16
|
+
status = yield
|
|
17
|
+
rescue ActiveRecord::Rollback
|
|
18
|
+
clear_transaction_record_state
|
|
19
|
+
status = nil
|
|
20
|
+
end
|
|
27
21
|
|
|
22
|
+
raise ActiveRecord::Rollback unless status
|
|
23
|
+
end
|
|
24
|
+
status
|
|
28
25
|
ensure
|
|
29
26
|
if @transaction_state && @transaction_state.committed?
|
|
30
27
|
clear_transaction_record_state
|
|
@@ -32,17 +29,15 @@ module ActiveRecord::Turntable
|
|
|
32
29
|
end
|
|
33
30
|
|
|
34
31
|
def add_to_transaction
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
sync_with_transaction_state
|
|
40
|
-
set_transaction_state(self.turntable_shard.connection.transaction_state)
|
|
41
|
-
end
|
|
42
|
-
remember_transaction_record_state
|
|
32
|
+
return super unless self.class.turntable_enabled?
|
|
33
|
+
|
|
34
|
+
if has_transactional_callbacks?
|
|
35
|
+
self.turntable_shard.connection.add_transaction_record(self)
|
|
43
36
|
else
|
|
44
|
-
|
|
37
|
+
sync_with_transaction_state
|
|
38
|
+
set_transaction_state(self.turntable_shard.connection.transaction_state)
|
|
45
39
|
end
|
|
40
|
+
remember_transaction_record_state
|
|
46
41
|
end
|
|
47
42
|
end
|
|
48
43
|
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module ActiveRecord::Turntable
|
|
2
|
+
module Compatibility
|
|
3
|
+
def self.extended(base)
|
|
4
|
+
base.instance_variable_set(:@_compatible_versions, [])
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def [](version = ActiveRecord.gem_version.release)
|
|
8
|
+
unless version.is_a?(Gem::Version)
|
|
9
|
+
version = Gem::Version.new(version)
|
|
10
|
+
end
|
|
11
|
+
find_compatible_module(version)
|
|
12
|
+
end
|
|
13
|
+
alias_method :compatible_module, :[]
|
|
14
|
+
|
|
15
|
+
def find_compatible_module(version)
|
|
16
|
+
module_version = find_compatible_version(version)
|
|
17
|
+
const_get("V#{module_version.to_s.tr(".", "_")}")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def find_compatible_version(version)
|
|
21
|
+
target_version = nil
|
|
22
|
+
|
|
23
|
+
compatible_versions.each do |compatible_version|
|
|
24
|
+
break if version < compatible_version
|
|
25
|
+
target_version = compatible_version
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
target_version
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def compatible_versions
|
|
32
|
+
if @_compatible_versions.empty?
|
|
33
|
+
@_compatible_versions = constants.map do |const|
|
|
34
|
+
/^V(?<major>\d+)(_(?<minor>\d+)(_(?<teeny>\d))?)?/ =~ const
|
|
35
|
+
nil unless major
|
|
36
|
+
Gem::Version.new([major, minor, teeny].compact.join("."))
|
|
37
|
+
end
|
|
38
|
+
@_compatible_versions.compact!
|
|
39
|
+
@_compatible_versions.sort!
|
|
40
|
+
end
|
|
41
|
+
@_compatible_versions
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -9,11 +9,16 @@ module ActiveRecord::Turntable
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def ar_version
|
|
12
|
-
ActiveRecord.gem_version
|
|
12
|
+
ActiveRecord.gem_version.release
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def ar51_or_later?
|
|
16
|
+
ar_version_equals_or_later?("5.1")
|
|
13
17
|
end
|
|
14
18
|
|
|
15
19
|
module_function :ar_version_equals_or_later?,
|
|
16
20
|
:ar_version_earlier_than?,
|
|
17
|
-
:ar_version
|
|
21
|
+
:ar_version,
|
|
22
|
+
:ar51_or_later?
|
|
18
23
|
end
|
|
19
24
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activerecord-turntable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0
|
|
4
|
+
version: 3.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- gussan
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2017-06-
|
|
12
|
+
date: 2017-06-16 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: activerecord
|
|
@@ -513,6 +513,8 @@ files:
|
|
|
513
513
|
- gemfiles/rails5_0_1.gemfile
|
|
514
514
|
- gemfiles/rails5_0_2.gemfile
|
|
515
515
|
- gemfiles/rails5_0_3.gemfile
|
|
516
|
+
- gemfiles/rails5_1_0.gemfile
|
|
517
|
+
- gemfiles/rails5_1_1.gemfile
|
|
516
518
|
- gemfiles/rails_edge.gemfile
|
|
517
519
|
- lib/active_record/turntable.rb
|
|
518
520
|
- lib/active_record/turntable/active_record_ext.rb
|
|
@@ -544,6 +546,7 @@ files:
|
|
|
544
546
|
- lib/active_record/turntable/base.rb
|
|
545
547
|
- lib/active_record/turntable/cluster.rb
|
|
546
548
|
- lib/active_record/turntable/cluster_helper_methods.rb
|
|
549
|
+
- lib/active_record/turntable/compatibility.rb
|
|
547
550
|
- lib/active_record/turntable/config.rb
|
|
548
551
|
- lib/active_record/turntable/connection_proxy.rb
|
|
549
552
|
- lib/active_record/turntable/connection_proxy/mixable.rb
|