db-charmer 1.8.4 → 1.9.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 +15 -0
- data/CHANGES +19 -0
- data/README.rdoc +12 -537
- data/lib/db_charmer.rb +17 -52
- data/lib/db_charmer/active_record/class_attributes.rb +42 -27
- data/lib/db_charmer/active_record/connection_switching.rb +17 -14
- data/lib/db_charmer/active_record/db_magic.rb +3 -2
- data/lib/db_charmer/connection_factory.rb +13 -5
- data/lib/db_charmer/connection_proxy.rb +30 -1
- data/lib/db_charmer/force_slave_reads.rb +27 -8
- data/lib/db_charmer/sharding/stub_connection.rb +6 -0
- data/lib/db_charmer/version.rb +2 -2
- data/lib/db_charmer/with_remapped_databases.rb +49 -0
- data/lib/tasks/databases.rake +5 -1
- metadata +14 -26
data/lib/db_charmer.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
require 'active_record/version' unless defined?(::ActiveRecord::VERSION::MAJOR)
|
3
3
|
require 'active_support/core_ext'
|
4
4
|
|
5
|
+
#---------------------------------------------------------------------------------------------------
|
5
6
|
module DbCharmer
|
6
7
|
# Configure autoload
|
7
8
|
autoload :Sharding, 'db_charmer/sharding'
|
@@ -68,64 +69,33 @@ module DbCharmer
|
|
68
69
|
::ActionController::Base.extend(DbCharmer::ActionController::ForceSlaveReads::ClassMethods)
|
69
70
|
::ActionController::Base.send(:include, DbCharmer::ActionController::ForceSlaveReads::InstanceMethods)
|
70
71
|
end
|
71
|
-
|
72
|
-
#-------------------------------------------------------------------------------------------------
|
73
|
-
def self.with_remapped_databases(mappings, &proc)
|
74
|
-
old_mappings = ::ActiveRecord::Base.db_charmer_database_remappings
|
75
|
-
begin
|
76
|
-
::ActiveRecord::Base.db_charmer_database_remappings = mappings
|
77
|
-
if mappings[:master] || mappings['master']
|
78
|
-
with_all_hijacked(&proc)
|
79
|
-
else
|
80
|
-
proc.call
|
81
|
-
end
|
82
|
-
ensure
|
83
|
-
::ActiveRecord::Base.db_charmer_database_remappings = old_mappings
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def self.hijack_new_classes?
|
88
|
-
@@hijack_new_classes
|
89
|
-
end
|
90
|
-
|
91
|
-
private
|
92
|
-
|
93
|
-
@@hijack_new_classes = false
|
94
|
-
def self.with_all_hijacked
|
95
|
-
old_hijack_new_classes = @@hijack_new_classes
|
96
|
-
begin
|
97
|
-
@@hijack_new_classes = true
|
98
|
-
subclasses_method = DbCharmer.rails3? ? :descendants : :subclasses
|
99
|
-
::ActiveRecord::Base.send(subclasses_method).each do |subclass|
|
100
|
-
subclass.hijack_connection!
|
101
|
-
end
|
102
|
-
yield
|
103
|
-
ensure
|
104
|
-
@@hijack_new_classes = old_hijack_new_classes
|
105
|
-
end
|
106
|
-
end
|
107
72
|
end
|
108
73
|
|
109
74
|
#---------------------------------------------------------------------------------------------------
|
110
75
|
# Print warning about the broken Rails 2.3.4
|
111
76
|
puts "WARNING: Rails 3.2.4 is not officially supported by DbCharmer. Please upgrade." if DbCharmer.rails324?
|
112
77
|
|
78
|
+
#---------------------------------------------------------------------------------------------------
|
113
79
|
# Add useful methods to global object
|
114
80
|
require 'db_charmer/core_extensions'
|
115
81
|
|
116
82
|
require 'db_charmer/connection_factory'
|
117
83
|
require 'db_charmer/connection_proxy'
|
118
84
|
require 'db_charmer/force_slave_reads'
|
85
|
+
require 'db_charmer/with_remapped_databases'
|
119
86
|
|
87
|
+
#---------------------------------------------------------------------------------------------------
|
120
88
|
# Add our custom class-level attributes to AR models
|
121
89
|
require 'db_charmer/active_record/class_attributes'
|
122
90
|
require 'active_record'
|
123
91
|
ActiveRecord::Base.extend(DbCharmer::ActiveRecord::ClassAttributes)
|
124
92
|
|
93
|
+
#---------------------------------------------------------------------------------------------------
|
125
94
|
# Enable connections switching in AR
|
126
95
|
require 'db_charmer/active_record/connection_switching'
|
127
96
|
ActiveRecord::Base.extend(DbCharmer::ActiveRecord::ConnectionSwitching)
|
128
97
|
|
98
|
+
#---------------------------------------------------------------------------------------------------
|
129
99
|
# Enable AR logging extensions
|
130
100
|
if DbCharmer.rails3?
|
131
101
|
require 'db_charmer/rails3/abstract_adapter/connection_name'
|
@@ -137,12 +107,14 @@ else
|
|
137
107
|
ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:include, DbCharmer::AbstractAdapter::LogFormatting)
|
138
108
|
end
|
139
109
|
|
110
|
+
#---------------------------------------------------------------------------------------------------
|
140
111
|
# Enable connection proxy in AR
|
141
112
|
require 'db_charmer/active_record/multi_db_proxy'
|
142
113
|
ActiveRecord::Base.extend(DbCharmer::ActiveRecord::MultiDbProxy::ClassMethods)
|
143
114
|
ActiveRecord::Base.extend(DbCharmer::ActiveRecord::MultiDbProxy::MasterSlaveClassMethods)
|
144
115
|
ActiveRecord::Base.send(:include, DbCharmer::ActiveRecord::MultiDbProxy::InstanceMethods)
|
145
116
|
|
117
|
+
#---------------------------------------------------------------------------------------------------
|
146
118
|
# Enable connection proxy for relations
|
147
119
|
if DbCharmer.rails3?
|
148
120
|
require 'db_charmer/rails3/active_record/relation_method'
|
@@ -151,15 +123,19 @@ if DbCharmer.rails3?
|
|
151
123
|
ActiveRecord::Relation.send(:include, DbCharmer::ActiveRecord::Relation::ConnectionRouting)
|
152
124
|
end
|
153
125
|
|
126
|
+
#---------------------------------------------------------------------------------------------------
|
154
127
|
# Enable connection proxy for scopes (rails 2.x only)
|
155
128
|
if DbCharmer.rails2?
|
156
129
|
require 'db_charmer/rails2/active_record/named_scope/scope_proxy'
|
157
130
|
ActiveRecord::NamedScope::Scope.send(:include, DbCharmer::ActiveRecord::NamedScope::ScopeProxy)
|
158
131
|
end
|
159
132
|
|
133
|
+
#---------------------------------------------------------------------------------------------------
|
160
134
|
# Enable connection proxy for associations
|
161
|
-
# WARNING: Inject methods to association class right here
|
162
|
-
|
135
|
+
# WARNING: Inject methods to association class right here because they proxy +include+ calls
|
136
|
+
# somewhere else, which means we could not use +include+ method here
|
137
|
+
association_proxy_class = DbCharmer.rails31? ? ActiveRecord::Associations::CollectionProxy :
|
138
|
+
ActiveRecord::Associations::AssociationProxy
|
163
139
|
association_proxy_class.class_eval do
|
164
140
|
def proxy?
|
165
141
|
true
|
@@ -194,6 +170,7 @@ association_proxy_class.class_eval do
|
|
194
170
|
end
|
195
171
|
end
|
196
172
|
|
173
|
+
#---------------------------------------------------------------------------------------------------
|
197
174
|
# Enable multi-db migrations
|
198
175
|
require 'db_charmer/active_record/migration/multi_db_migrations'
|
199
176
|
ActiveRecord::Migration.send(:include, DbCharmer::ActiveRecord::Migration::MultiDbMigrations)
|
@@ -203,6 +180,7 @@ if DbCharmer.rails31?
|
|
203
180
|
ActiveRecord::Migration::CommandRecorder.send(:include, DbCharmer::ActiveRecord::Migration::CommandRecorder)
|
204
181
|
end
|
205
182
|
|
183
|
+
#---------------------------------------------------------------------------------------------------
|
206
184
|
# Enable the magic
|
207
185
|
if DbCharmer.rails3?
|
208
186
|
require 'db_charmer/rails3/active_record/master_slave_routing'
|
@@ -214,6 +192,7 @@ require 'db_charmer/active_record/sharding'
|
|
214
192
|
require 'db_charmer/active_record/db_magic'
|
215
193
|
ActiveRecord::Base.extend(DbCharmer::ActiveRecord::DbMagic)
|
216
194
|
|
195
|
+
#---------------------------------------------------------------------------------------------------
|
217
196
|
# Setup association preload magic
|
218
197
|
if DbCharmer.rails31?
|
219
198
|
require 'db_charmer/rails31/active_record/preloader/association'
|
@@ -227,17 +206,3 @@ else
|
|
227
206
|
# Open up really useful API method
|
228
207
|
ActiveRecord::AssociationPreload::ClassMethods.send(:public, :preload_associations)
|
229
208
|
end
|
230
|
-
|
231
|
-
#---------------------------------------------------------------------------------------------------
|
232
|
-
# Hijack connection on all new AR classes when we're in a block with main AR connection remapped
|
233
|
-
class ActiveRecord::Base
|
234
|
-
class << self
|
235
|
-
def inherited_with_hijacking(subclass)
|
236
|
-
out = inherited_without_hijacking(subclass)
|
237
|
-
hijack_connection! if DbCharmer.hijack_new_classes?
|
238
|
-
out
|
239
|
-
end
|
240
|
-
|
241
|
-
alias_method_chain :inherited, :hijacking
|
242
|
-
end
|
243
|
-
end
|
@@ -10,17 +10,7 @@ module DbCharmer
|
|
10
10
|
@@db_charmer_opts[self.name] || {}
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
@@db_charmer_connection_proxies = {}
|
15
|
-
def db_charmer_connection_proxy=(proxy)
|
16
|
-
@@db_charmer_connection_proxies[self.name] = proxy
|
17
|
-
end
|
18
|
-
|
19
|
-
def db_charmer_connection_proxy
|
20
|
-
@@db_charmer_connection_proxies[self.name]
|
21
|
-
end
|
22
|
-
|
23
|
-
#-----------------------------------------------------------------------------
|
13
|
+
#---------------------------------------------------------------------------------------------
|
24
14
|
@@db_charmer_default_connections = {}
|
25
15
|
def db_charmer_default_connection=(conn)
|
26
16
|
@@db_charmer_default_connections[self.name] = conn
|
@@ -30,7 +20,7 @@ module DbCharmer
|
|
30
20
|
@@db_charmer_default_connections[self.name]
|
31
21
|
end
|
32
22
|
|
33
|
-
|
23
|
+
#---------------------------------------------------------------------------------------------
|
34
24
|
@@db_charmer_slaves = {}
|
35
25
|
def db_charmer_slaves=(slaves)
|
36
26
|
@@db_charmer_slaves[self.name] = slaves
|
@@ -40,19 +30,36 @@ module DbCharmer
|
|
40
30
|
@@db_charmer_slaves[self.name] || []
|
41
31
|
end
|
42
32
|
|
33
|
+
# Returns a random connection from the list of slaves configured for this AR class
|
43
34
|
def db_charmer_random_slave
|
44
35
|
return nil unless db_charmer_slaves.any?
|
45
36
|
db_charmer_slaves[rand(db_charmer_slaves.size)]
|
46
37
|
end
|
47
38
|
|
48
|
-
|
49
|
-
|
39
|
+
#---------------------------------------------------------------------------------------------
|
40
|
+
def db_charmer_connection_proxies
|
41
|
+
Thread.current[:db_charmer_connection_proxies] ||= {}
|
42
|
+
end
|
43
|
+
|
44
|
+
def db_charmer_connection_proxy=(proxy)
|
45
|
+
db_charmer_connection_proxies[self.name] = proxy
|
46
|
+
end
|
47
|
+
|
48
|
+
def db_charmer_connection_proxy
|
49
|
+
db_charmer_connection_proxies[self.name]
|
50
|
+
end
|
51
|
+
|
52
|
+
#---------------------------------------------------------------------------------------------
|
53
|
+
def db_charmer_force_slave_reads_flags
|
54
|
+
Thread.current[:db_charmer_force_slave_reads] ||= {}
|
55
|
+
end
|
56
|
+
|
50
57
|
def db_charmer_force_slave_reads=(force)
|
51
|
-
|
58
|
+
db_charmer_force_slave_reads_flags[self.name] = force
|
52
59
|
end
|
53
60
|
|
54
61
|
def db_charmer_force_slave_reads
|
55
|
-
|
62
|
+
db_charmer_force_slave_reads_flags[self.name]
|
56
63
|
end
|
57
64
|
|
58
65
|
# Slave reads are used in two cases:
|
@@ -62,39 +69,47 @@ module DbCharmer
|
|
62
69
|
db_charmer_force_slave_reads || DbCharmer.force_slave_reads?
|
63
70
|
end
|
64
71
|
|
65
|
-
|
66
|
-
|
72
|
+
#---------------------------------------------------------------------------------------------
|
73
|
+
def db_charmer_connection_levels
|
74
|
+
Thread.current[:db_charmer_connection_levels] ||= Hash.new(0)
|
75
|
+
end
|
76
|
+
|
67
77
|
def db_charmer_connection_level=(level)
|
68
|
-
|
78
|
+
db_charmer_connection_levels[self.name] = level
|
69
79
|
end
|
70
80
|
|
71
81
|
def db_charmer_connection_level
|
72
|
-
|
82
|
+
db_charmer_connection_levels[self.name] || 0
|
73
83
|
end
|
74
84
|
|
75
85
|
def db_charmer_top_level_connection?
|
76
86
|
db_charmer_connection_level.zero?
|
77
87
|
end
|
78
88
|
|
79
|
-
|
80
|
-
@@db_charmer_database_remappings = Hash.new
|
89
|
+
#---------------------------------------------------------------------------------------------
|
81
90
|
def db_charmer_remapped_connection
|
82
|
-
return nil
|
91
|
+
return nil unless db_charmer_top_level_connection?
|
83
92
|
name = :master
|
84
|
-
proxy =
|
93
|
+
proxy = db_charmer_model_connection_proxy
|
85
94
|
name = proxy.db_charmer_connection_name.to_sym if proxy
|
86
95
|
|
87
|
-
remapped =
|
96
|
+
remapped = db_charmer_database_remappings[name]
|
88
97
|
remapped ? DbCharmer::ConnectionFactory.connect(remapped, true) : nil
|
89
98
|
end
|
90
99
|
|
91
100
|
def db_charmer_database_remappings
|
92
|
-
|
101
|
+
Thread.current[:db_charmer_database_remappings] ||= Hash.new
|
93
102
|
end
|
94
103
|
|
95
104
|
def db_charmer_database_remappings=(mappings)
|
96
105
|
raise "Mappings must be nil or respond to []" if mappings && (! mappings.respond_to?(:[]))
|
97
|
-
|
106
|
+
Thread.current[:db_charmer_database_remappings] = mappings || {}
|
107
|
+
end
|
108
|
+
|
109
|
+
#---------------------------------------------------------------------------------------------
|
110
|
+
# Returns model-specific connection proxy, ignoring any global connection remappings
|
111
|
+
def db_charmer_model_connection_proxy
|
112
|
+
db_charmer_connection_proxy || db_charmer_default_connection
|
98
113
|
end
|
99
114
|
end
|
100
115
|
end
|
@@ -31,13 +31,13 @@ module DbCharmer
|
|
31
31
|
class << self
|
32
32
|
# Make sure we check our accessors before going to the default connection retrieval method
|
33
33
|
def connection_with_magic
|
34
|
-
db_charmer_remapped_connection ||
|
34
|
+
db_charmer_remapped_connection || db_charmer_model_connection_proxy || connection_without_magic
|
35
35
|
end
|
36
36
|
alias_method_chain :connection, :magic
|
37
37
|
|
38
38
|
def connection_pool_with_magic
|
39
|
-
|
40
|
-
|
39
|
+
if connection.respond_to?(:abstract_connection_class)
|
40
|
+
abstract_connection_class = connection.abstract_connection_class
|
41
41
|
connection_handler.retrieve_connection_pool(abstract_connection_class) || connection_pool_without_magic
|
42
42
|
else
|
43
43
|
connection_pool_without_magic
|
@@ -49,26 +49,31 @@ module DbCharmer
|
|
49
49
|
|
50
50
|
#-----------------------------------------------------------------------------------------------------------------
|
51
51
|
def coerce_to_connection_proxy(conn, should_exist = true)
|
52
|
+
# Return nil if given no connection specification
|
52
53
|
return nil if conn.nil?
|
53
54
|
|
55
|
+
# For sharded proxies just use them as-is
|
56
|
+
return conn if conn.respond_to?(:set_real_connection)
|
57
|
+
|
58
|
+
# For connection proxies and objects that could be coerced into a proxy just call the coercion method
|
59
|
+
return conn.db_charmer_connection_proxy if conn.respond_to?(:db_charmer_connection_proxy)
|
60
|
+
|
61
|
+
# For plain AR connection adapters, just use them as-is
|
62
|
+
return conn if conn.kind_of?(::ActiveRecord::ConnectionAdapters::AbstractAdapter)
|
63
|
+
|
64
|
+
# For connection names, use connection factory to create new connections
|
54
65
|
if conn.kind_of?(Symbol) || conn.kind_of?(String)
|
55
66
|
return DbCharmer::ConnectionFactory.connect(conn, should_exist)
|
56
67
|
end
|
57
68
|
|
69
|
+
# For connection configs (hashes), create connections
|
58
70
|
if conn.kind_of?(Hash)
|
59
71
|
conn = conn.symbolize_keys
|
60
72
|
raise ArgumentError, "Missing required :connection_name parameter" unless conn[:connection_name]
|
61
73
|
return DbCharmer::ConnectionFactory.connect_to_db(conn[:connection_name], conn)
|
62
74
|
end
|
63
75
|
|
64
|
-
|
65
|
-
return conn.db_charmer_connection_proxy
|
66
|
-
end
|
67
|
-
|
68
|
-
if conn.kind_of?(::ActiveRecord::ConnectionAdapters::AbstractAdapter) || conn.kind_of?(DbCharmer::Sharding::StubConnection)
|
69
|
-
return conn
|
70
|
-
end
|
71
|
-
|
76
|
+
# Fails for unsupported connection types
|
72
77
|
raise "Unsupported connection type: #{conn.class}"
|
73
78
|
end
|
74
79
|
|
@@ -76,14 +81,12 @@ module DbCharmer
|
|
76
81
|
def switch_connection_to(conn, should_exist = true)
|
77
82
|
new_conn = coerce_to_connection_proxy(conn, should_exist)
|
78
83
|
|
79
|
-
if db_charmer_connection_proxy.
|
84
|
+
if db_charmer_connection_proxy.respond_to?(:set_real_connection)
|
80
85
|
db_charmer_connection_proxy.set_real_connection(new_conn)
|
81
86
|
end
|
82
87
|
|
83
88
|
self.db_charmer_connection_proxy = new_conn
|
84
89
|
self.hijack_connection!
|
85
|
-
|
86
|
-
# self.reset_column_information
|
87
90
|
end
|
88
91
|
|
89
92
|
end
|
@@ -64,8 +64,9 @@ module DbCharmer
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def setup_connection_magic(conn, should_exist = true)
|
67
|
-
|
68
|
-
self.db_charmer_default_connection =
|
67
|
+
conn_proxy = coerce_to_connection_proxy(conn, should_exist)
|
68
|
+
self.db_charmer_default_connection = conn_proxy
|
69
|
+
switch_connection_to(conn_proxy, should_exist)
|
69
70
|
end
|
70
71
|
|
71
72
|
def setup_slaves_magic(slaves, force_slave_reads, should_exist = true)
|
@@ -6,22 +6,28 @@
|
|
6
6
|
#
|
7
7
|
module DbCharmer
|
8
8
|
module ConnectionFactory
|
9
|
-
|
9
|
+
def self.connection_classes
|
10
|
+
Thread.current[:db_charmer_generated_connection_classes] ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.connection_classes=(val)
|
14
|
+
Thread.current[:db_charmer_generated_connection_classes] = val
|
15
|
+
end
|
10
16
|
|
11
17
|
def self.reset!
|
12
|
-
|
18
|
+
self.connection_classes = {}
|
13
19
|
end
|
14
20
|
|
15
21
|
# Establishes connection or return an existing one from cache
|
16
22
|
def self.connect(connection_name, should_exist = true)
|
17
23
|
connection_name = connection_name.to_s
|
18
|
-
|
24
|
+
connection_classes[connection_name] ||= establish_connection(connection_name, should_exist)
|
19
25
|
end
|
20
26
|
|
21
27
|
# Establishes connection or return an existing one from cache (not using AR database configs)
|
22
28
|
def self.connect_to_db(connection_name, config)
|
23
29
|
connection_name = connection_name.to_s
|
24
|
-
|
30
|
+
connection_classes[connection_name] ||= establish_connection_to_db(connection_name, config)
|
25
31
|
end
|
26
32
|
|
27
33
|
# Establish connection with a specified name
|
@@ -70,7 +76,9 @@ module DbCharmer
|
|
70
76
|
|
71
77
|
# Generates unique names for our abstract AR classes
|
72
78
|
def self.abstract_connection_class_name(connection_name)
|
73
|
-
|
79
|
+
conn_name_klass = connection_name.to_s.gsub(/\W+/, '_').camelize
|
80
|
+
thread = Thread.current.object_id.abs # need to make sure it is non-negative
|
81
|
+
"::AutoGeneratedAbstractConnectionClass#{conn_name_klass}ForThread#{thread}"
|
74
82
|
end
|
75
83
|
end
|
76
84
|
end
|
@@ -20,8 +20,37 @@ module DbCharmer
|
|
20
20
|
self
|
21
21
|
end
|
22
22
|
|
23
|
+
def db_charmer_retrieve_connection
|
24
|
+
@abstract_connection_class.retrieve_connection
|
25
|
+
end
|
26
|
+
|
27
|
+
def nil?
|
28
|
+
false
|
29
|
+
end
|
30
|
+
|
31
|
+
#-----------------------------------------------------------------------------------------------
|
32
|
+
RESPOND_TO_METHODS = [
|
33
|
+
:abstract_connection_class,
|
34
|
+
:db_charmer_connection_name,
|
35
|
+
:db_charmer_connection_proxy,
|
36
|
+
:db_charmer_retrieve_connection,
|
37
|
+
:nil?
|
38
|
+
].freeze
|
39
|
+
|
40
|
+
# Short-circuit some of the methods for which we know there is a separate check in coercion code
|
41
|
+
DOESNT_RESPOND_TO_METHODS = [
|
42
|
+
:set_real_connection
|
43
|
+
].freeze
|
44
|
+
|
45
|
+
def respond_to?(method_name, include_all = false)
|
46
|
+
return true if RESPOND_TO_METHODS.include?(method_name)
|
47
|
+
return false if DOESNT_RESPOND_TO_METHODS.include?(method_name)
|
48
|
+
db_charmer_retrieve_connection.respond_to?(method_name, include_all)
|
49
|
+
end
|
50
|
+
|
51
|
+
#-----------------------------------------------------------------------------------------------
|
23
52
|
def method_missing(meth, *args, &block)
|
24
|
-
|
53
|
+
db_charmer_retrieve_connection.send(meth, *args, &block)
|
25
54
|
end
|
26
55
|
end
|
27
56
|
end
|
@@ -1,12 +1,25 @@
|
|
1
1
|
module DbCharmer
|
2
|
-
|
3
|
-
|
2
|
+
def self.current_controller
|
3
|
+
Thread.current[:db_charmer_current_controller]
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.current_controller=(val)
|
7
|
+
Thread.current[:db_charmer_current_controller] = val
|
8
|
+
end
|
9
|
+
|
10
|
+
#-------------------------------------------------------------------------------------------------
|
11
|
+
def self.forced_slave_reads_setting
|
12
|
+
Thread.current[:db_charmer_forced_slave_reads]
|
13
|
+
end
|
4
14
|
|
5
|
-
|
15
|
+
def self.forced_slave_reads_setting=(val)
|
16
|
+
Thread.current[:db_charmer_forced_slave_reads] = val
|
17
|
+
end
|
6
18
|
|
19
|
+
#-------------------------------------------------------------------------------------------------
|
7
20
|
def self.force_slave_reads?
|
8
21
|
# If global force slave reads is requested, do it
|
9
|
-
return
|
22
|
+
return true if Thread.current[:db_charmer_forced_slave_reads]
|
10
23
|
|
11
24
|
# If not, try to use current controller to decide on this
|
12
25
|
return false unless current_controller.respond_to?(:force_slave_reads?)
|
@@ -16,6 +29,7 @@ module DbCharmer
|
|
16
29
|
return slave_reads
|
17
30
|
end
|
18
31
|
|
32
|
+
#-------------------------------------------------------------------------------------------------
|
19
33
|
def self.with_controller(controller)
|
20
34
|
raise ArgumentError, "No block given" unless block_given?
|
21
35
|
logger.debug("Setting current controller for db_charmer: #{controller.class.name}")
|
@@ -26,11 +40,16 @@ module DbCharmer
|
|
26
40
|
self.current_controller = nil
|
27
41
|
end
|
28
42
|
|
43
|
+
#-------------------------------------------------------------------------------------------------
|
44
|
+
# Force all reads in a block of code to go to a slave
|
29
45
|
def self.force_slave_reads
|
30
46
|
raise ArgumentError, "No block given" unless block_given?
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
47
|
+
old_forced_slave_reads = self.forced_slave_reads_setting
|
48
|
+
begin
|
49
|
+
self.forced_slave_reads_setting = true
|
50
|
+
yield
|
51
|
+
ensure
|
52
|
+
self.forced_slave_reads_setting = old_forced_slave_reads
|
53
|
+
end
|
35
54
|
end
|
36
55
|
end
|