db-charmer 1.6.19 → 1.7.0.pre1
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.
- 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
|