db-charmer 1.6.19 → 1.7.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +14 -2
- data/README.rdoc +89 -4
- data/Rakefile +4 -0
- data/db-charmer.gemspec +17 -15
- data/lib/db_charmer.rb +34 -43
- data/lib/db_charmer/{abstract_adapter_extensions.rb → abstract_adapter/log_formatting.rb} +5 -3
- data/lib/db_charmer/action_controller/force_slave_reads.rb +65 -0
- data/lib/db_charmer/{association_preload.rb → active_record/association_preload.rb} +2 -2
- data/lib/db_charmer/{active_record_extensions.rb → active_record/class_attributes.rb} +19 -40
- data/lib/db_charmer/active_record/connection_switching.rb +77 -0
- data/lib/db_charmer/{db_magic.rb → active_record/db_magic.rb} +18 -8
- data/lib/db_charmer/active_record/finder_overrides.rb +61 -0
- data/lib/db_charmer/active_record/migration/multi_db_migrations.rb +71 -0
- data/lib/db_charmer/active_record/multi_db_proxy.rb +65 -0
- data/lib/db_charmer/active_record/named_scope/scope_proxy.rb +26 -0
- data/lib/db_charmer/active_record/sharding.rb +40 -0
- data/lib/db_charmer/connection_factory.rb +1 -1
- data/lib/db_charmer/core_extensions.rb +10 -0
- data/lib/db_charmer/force_slave_reads.rb +36 -0
- data/lib/db_charmer/sharding.rb +0 -36
- data/lib/db_charmer/sharding/method/db_block_group_map.rb +3 -3
- data/lib/db_charmer/sharding/method/db_block_map.rb +3 -3
- data/lib/db_charmer/sharding/stub_connection.rb +4 -4
- data/lib/db_charmer/version.rb +10 -0
- data/lib/tasks/databases.rake +6 -6
- metadata +28 -21
- data/VERSION +0 -1
- data/lib/db_charmer/connection_switch.rb +0 -40
- data/lib/db_charmer/finder_overrides.rb +0 -56
- data/lib/db_charmer/multi_db_migrations.rb +0 -67
- data/lib/db_charmer/multi_db_proxy.rb +0 -63
- data/lib/db_charmer/scope_proxy.rb +0 -22
data/CHANGES
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
1.7.0 (not released yet):
|
2
|
+
|
3
|
+
Beta feature: Added force_slave_reads functionality. Now we could have models with slaves
|
4
|
+
that are not used by default, but could be turned on globally (per-controller or per-action).
|
5
|
+
|
6
|
+
Heavily reorganized the source code to match Rails code structure (class names, etc). This should
|
7
|
+
make it much easier for other contributors to work with the code.
|
8
|
+
Added smarter environment detection (using Rails.env, RAILS_ENV or RACK_ENV).
|
9
|
+
|
10
|
+
Bugfixes: Fix for N+1 queries when accessing shard_info for db_block_group_map sharding method.
|
11
|
+
|
12
|
+
----------------------------------------------------------------------------------------
|
1
13
|
1.6.17-19 (2011-04-25):
|
2
14
|
|
3
15
|
Bugfixes: Do not touch database for sharded models until we really need to. Before 1.6.17
|
@@ -13,10 +25,10 @@ being used with db-charmer gem.
|
|
13
25
|
----------------------------------------------------------------------------------------
|
14
26
|
1.6.13 (2010-08-17):
|
15
27
|
|
16
|
-
Starting with this version we use Rails.env instead of RAILS_ENV to auto-detect rails
|
28
|
+
Starting with this version we use Rails.env instead of RAILS_ENV to auto-detect rails
|
17
29
|
environment. If you use DbCharmer in non-rails project, please set DbCharmer.env manually.
|
18
30
|
|
19
|
-
Bugfixes: Thanks to Eric Lindvall we now allow connection names that have symbols ruby
|
31
|
+
Bugfixes: Thanks to Eric Lindvall we now allow connection names that have symbols ruby
|
20
32
|
wouldn't like for class names.
|
21
33
|
|
22
34
|
----------------------------------------------------------------------------------------
|
data/README.rdoc
CHANGED
@@ -28,7 +28,7 @@ To install db-charmer as a Rails plugin use this:
|
|
28
28
|
script/plugin install git://github.com/kovyrin/db-charmer.git
|
29
29
|
|
30
30
|
_Notice_: If you use db-charmer in a non-rails project, you may need to set <tt>DbCharmer.env</tt> to a correct value
|
31
|
-
before using any of its connection management methods. Correct value here is a valid <tt>database.yml</tt>
|
31
|
+
before using any of its connection management methods. Correct value here is a valid <tt>database.yml</tt>
|
32
32
|
first-level section name.
|
33
33
|
|
34
34
|
|
@@ -52,6 +52,21 @@ Sample code:
|
|
52
52
|
Foo.switch_connection_to(Baz.connection)
|
53
53
|
Foo.switch_connection_to(nil)
|
54
54
|
|
55
|
+
Sample <tt>database.yml</tt> configuration:
|
56
|
+
|
57
|
+
production:
|
58
|
+
blah:
|
59
|
+
adapter: mysql
|
60
|
+
username: blah
|
61
|
+
host: blah.local
|
62
|
+
database: blah
|
63
|
+
|
64
|
+
foo:
|
65
|
+
adapter: mysql
|
66
|
+
username: foo
|
67
|
+
host: foo.local
|
68
|
+
database: foo
|
69
|
+
|
55
70
|
The +switch_connection_to+ method has an optional second parameter +should_exist+ which is true
|
56
71
|
by default. This parameter is used when the method is called with a string or a symbol connection
|
57
72
|
name and there is no such connection configuration in the database.yml file. If this parameter
|
@@ -243,6 +258,65 @@ This behaviour is controlled by the <tt>DbCharmer.connections_should_exist</tt>
|
|
243
258
|
configuration attribute which could be set from a rails initializer.
|
244
259
|
|
245
260
|
|
261
|
+
=== Forced Slave Reads
|
262
|
+
|
263
|
+
In some cases we could have models that are too important to be used in default "send all
|
264
|
+
reads to the slave" mode, but we still would like to be able to switch them to this mode
|
265
|
+
sometimes. For example, you could have +User+ model, which you would like to keep from
|
266
|
+
lagging with your slaves because users do not like to see outdated information about their
|
267
|
+
accounts. But in some cases (like logged-out profile page views, etc) it would be perfectly
|
268
|
+
reasonable to switch all reads to the slave.
|
269
|
+
|
270
|
+
For this use-case starting with +DbCharmer+ release 1.7.0 we have a feature called forced
|
271
|
+
slave reads. It consists of a few separate small features that together make it really
|
272
|
+
powerful:
|
273
|
+
|
274
|
+
1) <tt>:force_slave_reads => false</tt> option for +ActiveRecord+'s <tt>db_magic</tt> method.
|
275
|
+
This option could be used to disable automated slave reads on your models so that you could
|
276
|
+
call <tt>on_slave</tt> or use other methods to enable slave reads when you need it. Example:
|
277
|
+
|
278
|
+
class User < ActiveRecord::Base
|
279
|
+
db_magic :slave => slave01, :forced_slave_reads => false
|
280
|
+
end
|
281
|
+
|
282
|
+
2) <tt>force_slave_reads</tt> +ActionController+ class method. This method could be used to
|
283
|
+
enable per-controller (when called with no arguments), or per-action (<tt>:only</tt> and
|
284
|
+
<tt>:except</tt> params) forced reads from slaves. This is really useful for actions in
|
285
|
+
which you know you could tolerate some slave lag so all your models with slaves defined will
|
286
|
+
send their reads to slaves. Example:
|
287
|
+
|
288
|
+
class ProfilesController < Application
|
289
|
+
force_slave_reads :except => [ :login, :logout ]
|
290
|
+
...
|
291
|
+
end
|
292
|
+
|
293
|
+
3) <tt>force_slave_reads!</tt> +ActionController+ instance method, that could be used within
|
294
|
+
your actions or in controller filters to temporarily switch your models to forced slave reads
|
295
|
+
mode. This could be useful for cases when the same actions could be called by logged-in and
|
296
|
+
anonymous users. Then you could authorize users in <tt>before_filter</tt> and call
|
297
|
+
<tt>force_slave_reads!</tt> method for anonymous page views.
|
298
|
+
|
299
|
+
class ProfilesController < Application
|
300
|
+
before_filter do
|
301
|
+
force_slave_reads! unless current_user
|
302
|
+
end
|
303
|
+
...
|
304
|
+
end
|
305
|
+
|
306
|
+
4) <tt>DbCharmer.force_slave_reads</tt> method that could be used with a block of ruby code
|
307
|
+
and would enable forced slave reads mode until the end of the block execution. This is really
|
308
|
+
powerful feature allowing high granularity in your control of forced slave reads mode. Example:
|
309
|
+
|
310
|
+
DbCharmer.force_slave_reads do
|
311
|
+
...
|
312
|
+
total_users = User.count
|
313
|
+
...
|
314
|
+
end
|
315
|
+
|
316
|
+
Notice: At this point the feature considered beta and should be used with caution. It is fully covered
|
317
|
+
with tests, but there still could be unexpected issues when used in real-world applications.
|
318
|
+
|
319
|
+
|
246
320
|
=== Associations Connection Management
|
247
321
|
|
248
322
|
ActiveRecord models can have an associations with each other and since every model has its
|
@@ -492,12 +566,23 @@ most of the parts of plugin's code.
|
|
492
566
|
|
493
567
|
== What Ruby and Rails implementations does it work for?
|
494
568
|
|
495
|
-
We have a continuous integration setups for this plugin on MRI 1.8.
|
496
|
-
We use the plugin in production on Scribd.com with MRI (rubyee) 1.8.
|
569
|
+
We have a continuous integration setups for this plugin on MRI 1.8.7 with Rails 2.2 and 2.3.
|
570
|
+
We use the plugin in production on Scribd.com with MRI (rubyee) 1.8.7 and Rails 2.2, Rails 2.3,
|
571
|
+
Sinatra and plain Rack applications.
|
497
572
|
|
498
573
|
|
499
574
|
== Who are the authors?
|
500
575
|
|
501
576
|
This plugin has been created in Scribd.com for our internal use and then the sources were opened for
|
502
|
-
other people to use.
|
577
|
+
other people to use. Most of the code in this package has been developed by Alexey Kovyrin for Scribd.com
|
503
578
|
and is released under the MIT license. For more details, see the LICENSE file.
|
579
|
+
|
580
|
+
Other contributors who have helped with the development of this library are (alphabetically ordered):
|
581
|
+
* Allen Madsen
|
582
|
+
* Andrew Geweke
|
583
|
+
* Ashley Martens
|
584
|
+
* Dmytro Shteflyuk
|
585
|
+
* Eric Lindvall
|
586
|
+
* Gregory Man
|
587
|
+
* Michael Birk
|
588
|
+
* Tyler McMullen
|
data/Rakefile
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
begin
|
2
2
|
require 'jeweler'
|
3
|
+
require './lib/db_charmer/version.rb'
|
4
|
+
|
3
5
|
Jeweler::Tasks.new do |gemspec|
|
4
6
|
gemspec.name = 'db-charmer'
|
5
7
|
gemspec.summary = 'ActiveRecord Connections Magic'
|
@@ -8,6 +10,8 @@ begin
|
|
8
10
|
gemspec.homepage = 'http://github.com/kovyrin/db-charmer'
|
9
11
|
gemspec.authors = ['Alexey Kovyrin']
|
10
12
|
|
13
|
+
gemspec.version = DbCharmer::Version::STRING
|
14
|
+
|
11
15
|
gemspec.add_dependency('rails', '~> 2.2')
|
12
16
|
gemspec.add_dependency('blankslate', '>= 0')
|
13
17
|
end
|
data/db-charmer.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{db-charmer}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.7.0.pre1"
|
9
9
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Alexey Kovyrin"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-05-16}
|
13
13
|
s.description = %q{ActiveRecord Connections Magic (slaves, multiple connections, etc)}
|
14
14
|
s.email = %q{alexey@kovyrin.net}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -23,22 +23,24 @@ Gem::Specification.new do |s|
|
|
23
23
|
"Makefile",
|
24
24
|
"README.rdoc",
|
25
25
|
"Rakefile",
|
26
|
-
"VERSION",
|
27
26
|
"db-charmer.gemspec",
|
28
27
|
"init.rb",
|
29
28
|
"lib/db_charmer.rb",
|
30
|
-
"lib/db_charmer/
|
31
|
-
"lib/db_charmer/
|
32
|
-
"lib/db_charmer/association_preload.rb",
|
29
|
+
"lib/db_charmer/abstract_adapter/log_formatting.rb",
|
30
|
+
"lib/db_charmer/action_controller/force_slave_reads.rb",
|
31
|
+
"lib/db_charmer/active_record/association_preload.rb",
|
32
|
+
"lib/db_charmer/active_record/class_attributes.rb",
|
33
|
+
"lib/db_charmer/active_record/connection_switching.rb",
|
34
|
+
"lib/db_charmer/active_record/db_magic.rb",
|
35
|
+
"lib/db_charmer/active_record/finder_overrides.rb",
|
36
|
+
"lib/db_charmer/active_record/migration/multi_db_migrations.rb",
|
37
|
+
"lib/db_charmer/active_record/multi_db_proxy.rb",
|
38
|
+
"lib/db_charmer/active_record/named_scope/scope_proxy.rb",
|
39
|
+
"lib/db_charmer/active_record/sharding.rb",
|
33
40
|
"lib/db_charmer/connection_factory.rb",
|
34
41
|
"lib/db_charmer/connection_proxy.rb",
|
35
|
-
"lib/db_charmer/connection_switch.rb",
|
36
42
|
"lib/db_charmer/core_extensions.rb",
|
37
|
-
"lib/db_charmer/
|
38
|
-
"lib/db_charmer/finder_overrides.rb",
|
39
|
-
"lib/db_charmer/multi_db_migrations.rb",
|
40
|
-
"lib/db_charmer/multi_db_proxy.rb",
|
41
|
-
"lib/db_charmer/scope_proxy.rb",
|
43
|
+
"lib/db_charmer/force_slave_reads.rb",
|
42
44
|
"lib/db_charmer/sharding.rb",
|
43
45
|
"lib/db_charmer/sharding/connection.rb",
|
44
46
|
"lib/db_charmer/sharding/method/db_block_group_map.rb",
|
@@ -46,16 +48,16 @@ Gem::Specification.new do |s|
|
|
46
48
|
"lib/db_charmer/sharding/method/hash_map.rb",
|
47
49
|
"lib/db_charmer/sharding/method/range.rb",
|
48
50
|
"lib/db_charmer/sharding/stub_connection.rb",
|
51
|
+
"lib/db_charmer/version.rb",
|
49
52
|
"lib/tasks/databases.rake"
|
50
53
|
]
|
51
54
|
s.homepage = %q{http://github.com/kovyrin/db-charmer}
|
52
55
|
s.rdoc_options = ["--charset=UTF-8"]
|
53
56
|
s.require_paths = ["lib"]
|
54
|
-
s.rubygems_version = %q{1.
|
57
|
+
s.rubygems_version = %q{1.6.2}
|
55
58
|
s.summary = %q{ActiveRecord Connections Magic}
|
56
59
|
|
57
60
|
if s.respond_to? :specification_version then
|
58
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
59
61
|
s.specification_version = 3
|
60
62
|
|
61
63
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
data/lib/db_charmer.rb
CHANGED
@@ -2,7 +2,16 @@ module DbCharmer
|
|
2
2
|
@@connections_should_exist = true
|
3
3
|
mattr_accessor :connections_should_exist
|
4
4
|
|
5
|
-
|
5
|
+
# Try to detect current environment or use development by default
|
6
|
+
if defined?(Rails)
|
7
|
+
@@env = Rails.env
|
8
|
+
elsif ENV['RAILS_ENV']
|
9
|
+
@@env = ENV['RAILS_ENV']
|
10
|
+
elsif ENV['RACK_ENV']
|
11
|
+
@@env = ENV['RACK_ENV']
|
12
|
+
else
|
13
|
+
@@env = 'development'
|
14
|
+
end
|
6
15
|
mattr_accessor :env
|
7
16
|
|
8
17
|
def self.connections_should_exist?
|
@@ -15,16 +24,16 @@ module DbCharmer
|
|
15
24
|
end
|
16
25
|
|
17
26
|
def self.with_remapped_databases(mappings, &proc)
|
18
|
-
old_mappings = ActiveRecord::Base.db_charmer_database_remappings
|
27
|
+
old_mappings = ::ActiveRecord::Base.db_charmer_database_remappings
|
19
28
|
begin
|
20
|
-
ActiveRecord::Base.db_charmer_database_remappings = mappings
|
29
|
+
::ActiveRecord::Base.db_charmer_database_remappings = mappings
|
21
30
|
if mappings[:master] || mappings['master']
|
22
31
|
with_all_hijacked(&proc)
|
23
32
|
else
|
24
33
|
proc.call
|
25
34
|
end
|
26
35
|
ensure
|
27
|
-
ActiveRecord::Base.db_charmer_database_remappings = old_mappings
|
36
|
+
::ActiveRecord::Base.db_charmer_database_remappings = old_mappings
|
28
37
|
end
|
29
38
|
end
|
30
39
|
|
@@ -39,7 +48,7 @@ private
|
|
39
48
|
old_hijack_new_classes = @@hijack_new_classes
|
40
49
|
begin
|
41
50
|
@@hijack_new_classes = true
|
42
|
-
ActiveRecord::Base.send(:subclasses).each do |subclass|
|
51
|
+
::ActiveRecord::Base.send(:subclasses).each do |subclass|
|
43
52
|
subclass.hijack_connection!
|
44
53
|
end
|
45
54
|
yield
|
@@ -49,45 +58,32 @@ private
|
|
49
58
|
end
|
50
59
|
end
|
51
60
|
|
52
|
-
# These methods are added to all objects so we could call proxy? on anything
|
53
|
-
# and figure if an object is a proxy w/o hitting method_missing or respond_to?
|
54
|
-
class Object
|
55
|
-
def self.proxy?
|
56
|
-
false
|
57
|
-
end
|
58
|
-
|
59
|
-
def proxy?
|
60
|
-
false
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
61
|
# We need blankslate for all the proxies we have
|
65
62
|
require 'blankslate'
|
66
63
|
|
67
|
-
|
68
|
-
require 'db_charmer/abstract_adapter_extensions'
|
64
|
+
# Add useful methods to global object
|
69
65
|
require 'db_charmer/core_extensions'
|
70
66
|
|
71
67
|
require 'db_charmer/connection_factory'
|
72
68
|
require 'db_charmer/connection_proxy'
|
73
|
-
require 'db_charmer/
|
74
|
-
require 'db_charmer/scope_proxy'
|
75
|
-
require 'db_charmer/multi_db_proxy'
|
69
|
+
require 'db_charmer/force_slave_reads'
|
76
70
|
|
77
|
-
#
|
78
|
-
ActiveRecord::Base.extend(DbCharmer::
|
79
|
-
ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:include, DbCharmer::AbstractAdapterExtensions::InstanceMethods)
|
71
|
+
# Add our custom class-level attributes to AR models
|
72
|
+
ActiveRecord::Base.extend(DbCharmer::ActiveRecord::ClassAttributes)
|
80
73
|
|
81
74
|
# Enable connections switching in AR
|
82
|
-
ActiveRecord::Base.extend(DbCharmer::
|
75
|
+
ActiveRecord::Base.extend(DbCharmer::ActiveRecord::ConnectionSwitching)
|
76
|
+
|
77
|
+
# Enable misc AR extensions
|
78
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:include, DbCharmer::AbstractAdapter::LogFormatting)
|
83
79
|
|
84
80
|
# Enable connection proxy in AR
|
85
|
-
ActiveRecord::Base.extend(DbCharmer::MultiDbProxy::ClassMethods)
|
86
|
-
ActiveRecord::Base.extend(DbCharmer::MultiDbProxy::MasterSlaveClassMethods)
|
87
|
-
ActiveRecord::Base.send(:include, DbCharmer::MultiDbProxy::InstanceMethods)
|
81
|
+
ActiveRecord::Base.extend(DbCharmer::ActiveRecord::MultiDbProxy::ClassMethods)
|
82
|
+
ActiveRecord::Base.extend(DbCharmer::ActiveRecord::MultiDbProxy::MasterSlaveClassMethods)
|
83
|
+
ActiveRecord::Base.send(:include, DbCharmer::ActiveRecord::MultiDbProxy::InstanceMethods)
|
88
84
|
|
89
85
|
# Enable connection proxy for scopes
|
90
|
-
ActiveRecord::NamedScope::Scope.send(:include, DbCharmer::ScopeProxy
|
86
|
+
ActiveRecord::NamedScope::Scope.send(:include, DbCharmer::ActiveRecord::NamedScope::ScopeProxy)
|
91
87
|
|
92
88
|
# Enable connection proxy for associations
|
93
89
|
# WARNING: Inject methods to association class right here (they proxy include calls somewhere else, so include does not work)
|
@@ -114,24 +110,14 @@ module ActiveRecord
|
|
114
110
|
end
|
115
111
|
end
|
116
112
|
|
117
|
-
require 'db_charmer/db_magic'
|
118
|
-
require 'db_charmer/finder_overrides'
|
119
|
-
require 'db_charmer/association_preload'
|
120
|
-
require 'db_charmer/multi_db_migrations'
|
121
|
-
require 'db_charmer/multi_db_proxy'
|
122
|
-
|
123
|
-
require 'db_charmer/sharding'
|
124
|
-
require 'db_charmer/sharding/connection'
|
125
|
-
require 'db_charmer/sharding/stub_connection'
|
126
|
-
|
127
113
|
# Enable multi-db migrations
|
128
|
-
ActiveRecord::Migration.extend(DbCharmer::MultiDbMigrations)
|
114
|
+
ActiveRecord::Migration.extend(DbCharmer::ActiveRecord::Migration::MultiDbMigrations)
|
129
115
|
|
130
116
|
# Enable the magic
|
131
|
-
ActiveRecord::Base.extend(DbCharmer::DbMagic
|
117
|
+
ActiveRecord::Base.extend(DbCharmer::ActiveRecord::DbMagic)
|
132
118
|
|
133
119
|
# Setup association preload magic
|
134
|
-
ActiveRecord::Base.extend(DbCharmer::AssociationPreload
|
120
|
+
ActiveRecord::Base.extend(DbCharmer::ActiveRecord::AssociationPreload)
|
135
121
|
|
136
122
|
# Open up really useful API method
|
137
123
|
ActiveRecord::AssociationPreload::ClassMethods.send(:public, :preload_associations)
|
@@ -147,3 +133,8 @@ class ActiveRecord::Base
|
|
147
133
|
alias_method_chain :inherited, :hijacking
|
148
134
|
end
|
149
135
|
end
|
136
|
+
|
137
|
+
#-----------------------------------------------------------------------------------------------------------------------
|
138
|
+
# Extend ActionController to support forcing slave reads
|
139
|
+
ActionController::Base.extend(DbCharmer::ActionController::ForceSlaveReads::ClassMethods)
|
140
|
+
ActionController::Base.send(:include, DbCharmer::ActionController::ForceSlaveReads::InstanceMethods)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module DbCharmer
|
2
|
-
module
|
3
|
-
module
|
2
|
+
module AbstractAdapter
|
3
|
+
module LogFormatting
|
4
|
+
|
4
5
|
def self.included(base)
|
5
6
|
base.alias_method_chain :format_log_entry, :connection_name
|
6
7
|
end
|
@@ -12,9 +13,10 @@ module DbCharmer
|
|
12
13
|
|
13
14
|
def format_log_entry_with_connection_name(message, dump = nil)
|
14
15
|
msg = connection_name ? "[#{connection_name}] " : ''
|
15
|
-
msg = " \e[0;34;1m#{msg}\e[0m" if connection_name && ActiveRecord::Base.colorize_logging
|
16
|
+
msg = " \e[0;34;1m#{msg}\e[0m" if connection_name && ::ActiveRecord::Base.colorize_logging
|
16
17
|
msg << format_log_entry_without_connection_name(message, dump)
|
17
18
|
end
|
19
|
+
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module DbCharmer
|
2
|
+
module ActionController
|
3
|
+
module ForceSlaveReads
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
@@db_charmer_force_slave_reads_actions = {}
|
7
|
+
def force_slave_reads(params)
|
8
|
+
@@db_charmer_force_slave_reads_actions[self.name] = {
|
9
|
+
:except => params[:except] ? [*params[:except]].map(&:to_s) : [],
|
10
|
+
:only => params[:only] ? [*params[:only]].map(&:to_s) : []
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
def force_slave_reads_options
|
15
|
+
@@db_charmer_force_slave_reads_actions[self.name]
|
16
|
+
end
|
17
|
+
|
18
|
+
def force_slave_reads_action?(name = nil)
|
19
|
+
name = name.to_s
|
20
|
+
|
21
|
+
options = force_slave_reads_options
|
22
|
+
# If no options were defined for this controller, all actions are not forced to use slaves
|
23
|
+
return false unless options
|
24
|
+
|
25
|
+
# Actions where force_slave_reads mode was turned off
|
26
|
+
return false if options[:except].include?(name)
|
27
|
+
|
28
|
+
# Only for these actions force_slave_reads was turned on
|
29
|
+
return options[:only].include?(name) if options[:only].any?
|
30
|
+
|
31
|
+
# If :except is not empty, we're done with the checks and rest of the actions are should force slave reads
|
32
|
+
# Otherwise, all the actions are not in force_slave_reads mode
|
33
|
+
options[:except].any?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module InstanceMethods
|
38
|
+
def self.included(base)
|
39
|
+
base.alias_method_chain :perform_action, :forced_slave_reads
|
40
|
+
end
|
41
|
+
|
42
|
+
def force_slave_reads!
|
43
|
+
@db_charmer_force_slave_reads = true
|
44
|
+
end
|
45
|
+
|
46
|
+
def dont_force_slave_reads!
|
47
|
+
@db_charmer_force_slave_reads = false
|
48
|
+
end
|
49
|
+
|
50
|
+
def force_slave_reads?
|
51
|
+
@db_charmer_force_slave_reads || self.class.force_slave_reads_action?(params[:action])
|
52
|
+
end
|
53
|
+
|
54
|
+
protected
|
55
|
+
|
56
|
+
def perform_action_with_forced_slave_reads
|
57
|
+
DbCharmer.with_controller(self) do
|
58
|
+
perform_action_without_forced_slave_reads
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|