activerecord-turntable 3.0.1 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|