Module: DbCharmer::ActiveRecord::Relation::ConnectionRouting
- Defined in:
- lib/db_charmer/rails3/active_record/relation/connection_routing.rb
Constant Summary collapse
- SLAVE_METHODS =
All the methods that could be querying the database
[ :calculate, :exists? ]
- MASTER_METHODS =
[ :delete, :delete_all, :destroy, :destroy_all, :reload, :update, :update_all ]
- ALL_METHODS =
SLAVE_METHODS + MASTER_METHODS
- DB_CHARMER_ATTRIBUTES =
[ :db_charmer_connection, :db_charmer_connection_is_forced, :db_charmer_enable_slaves ]
Class Method Summary collapse
-
.aliased_method_name(target, with) ⇒ Object
Need this to mimick alias_method_chain name generation (exists? => exists_with_db_charmer?).
-
.included(base) ⇒ Object
Define the default relation connection + override all the query methods here.
-
.init_attributes(base) ⇒ Object
Define our attributes + spawn methods shit needs to be changed to make sure our accessors are copied over to the new instances.
-
.init_routing(base) ⇒ Object
Override all query methods.
Instance Method Summary collapse
-
#connection ⇒ Object
Make sure we get the right connection here.
-
#copy_db_charmer_options(src, dst) ⇒ Object
Copy our accessors from one instance to another.
-
#except_with_db_charmer(*args) ⇒ Object
Copy db_charmer attributes in addition to what they’re copying.
-
#on_db(con, &block) ⇒ Object
Connection switching (changes the default relation connection).
-
#only_with_db_charmer(*args) ⇒ Object
Copy db_charmer attributes in addition to what they’re copying.
-
#select_destination(method, recommendation = :default) ⇒ Object
Selects preferred destination (master/slave/default) for a query.
-
#switch_connection_for_method(method, recommendation = nil) ⇒ Object
Switch the model to default relation connection.
-
#to_a_with_db_charmer(*args, &block) ⇒ Object
For normal selects we go to the slave, but for selects with a lock we should use master.
Class Method Details
.aliased_method_name(target, with) ⇒ Object
Need this to mimick alias_method_chain name generation (exists? => exists_with_db_charmer?)
128 129 130 131 |
# File 'lib/db_charmer/rails3/active_record/relation/connection_routing.rb', line 128 def self.aliased_method_name(target, with) aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1 "#{aliased_target}_#{with}_db_charmer#{punctuation}" end |
.included(base) ⇒ Object
Define the default relation connection + override all the query methods here
14 15 16 17 |
# File 'lib/db_charmer/rails3/active_record/relation/connection_routing.rb', line 14 def self.included(base) init_attributes(base) init_routing(base) end |
.init_attributes(base) ⇒ Object
Define our attributes + spawn methods shit needs to be changed to make sure our accessors are copied over to the new instances
20 21 22 23 24 25 26 27 28 |
# File 'lib/db_charmer/rails3/active_record/relation/connection_routing.rb', line 20 def self.init_attributes(base) DB_CHARMER_ATTRIBUTES.each do |attr| base.send(:attr_accessor, attr) end # Override spawn methods base.alias_method_chain :except, :db_charmer base.alias_method_chain :only, :db_charmer end |
.init_routing(base) ⇒ Object
Override all query methods
31 32 33 34 35 36 37 38 |
# File 'lib/db_charmer/rails3/active_record/relation/connection_routing.rb', line 31 def self.init_routing(base) ALL_METHODS.each do |meth| base.alias_method_chain meth, :db_charmer end # Special case: for normal selects we go to the slave, but for selects with a lock we should use master base.alias_method_chain :to_a, :db_charmer end |
Instance Method Details
#connection ⇒ Object
Make sure we get the right connection here
74 75 76 |
# File 'lib/db_charmer/rails3/active_record/relation/connection_routing.rb', line 74 def connection @klass.on_db(db_charmer_connection).connection end |
#copy_db_charmer_options(src, dst) ⇒ Object
Copy our accessors from one instance to another
55 56 57 58 59 |
# File 'lib/db_charmer/rails3/active_record/relation/connection_routing.rb', line 55 def (src, dst) DB_CHARMER_ATTRIBUTES.each do |attr| dst.send("#{attr}=".to_sym, src.send(attr)) end end |
#except_with_db_charmer(*args) ⇒ Object
Copy db_charmer attributes in addition to what they’re copying
41 42 43 44 45 |
# File 'lib/db_charmer/rails3/active_record/relation/connection_routing.rb', line 41 def except_with_db_charmer(*args) except_without_db_charmer(*args).tap do |result| (self, result) end end |
#on_db(con, &block) ⇒ Object
Connection switching (changes the default relation connection)
62 63 64 65 66 67 68 69 70 71 |
# File 'lib/db_charmer/rails3/active_record/relation/connection_routing.rb', line 62 def on_db(con, &block) if block_given? @klass.on_db(con, &block) else clone.tap do |result| result.db_charmer_connection = con result.db_charmer_connection_is_forced = true end end end |
#only_with_db_charmer(*args) ⇒ Object
Copy db_charmer attributes in addition to what they’re copying
48 49 50 51 52 |
# File 'lib/db_charmer/rails3/active_record/relation/connection_routing.rb', line 48 def only_with_db_charmer(*args) only_without_db_charmer(*args).tap do |result| (self, result) end end |
#select_destination(method, recommendation = :default) ⇒ Object
Selects preferred destination (master/slave/default) for a query
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/db_charmer/rails3/active_record/relation/connection_routing.rb', line 79 def select_destination(method, recommendation = :default) # If this relation was created within a forced connection block (e.g Model.on_db(:foo).relation) # Then we should use that connection everywhere except cases when a model is slave-enabled # in those cases DML queries go to the master if db_charmer_connection_is_forced return :master if db_charmer_enable_slaves && MASTER_METHODS.member?(method) return :default end # If this relation is created from a slave-enabled model, let's do the routing if possible if db_charmer_enable_slaves return :slave if SLAVE_METHODS.member?(method) return :master if MASTER_METHODS.member?(method) else # Make sure we do not use recommended destination recommendation = :default end # If nothing else came up, let's use the default or recommended connection return recommendation end |
#switch_connection_for_method(method, recommendation = nil) ⇒ Object
Switch the model to default relation connection
102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/db_charmer/rails3/active_record/relation/connection_routing.rb', line 102 def switch_connection_for_method(method, recommendation = nil) # Choose where to send the query destination ||= select_destination(method, recommendation) # What method to use on_db_method = [ :on_db, db_charmer_connection ] on_db_method = :on_master if destination == :master on_db_method = :first_level_on_slave if destination == :slave # Perform the query @klass.send(*on_db_method) do yield end end |
#to_a_with_db_charmer(*args, &block) ⇒ Object
For normal selects we go to the slave, but for selects with a lock we should use master
118 119 120 121 122 123 124 125 |
# File 'lib/db_charmer/rails3/active_record/relation/connection_routing.rb', line 118 def to_a_with_db_charmer(*args, &block) preferred_destination = :slave preferred_destination = :master if lock_value switch_connection_for_method(:to_a, preferred_destination) do to_a_without_db_charmer(*args, &block) end end |