Module: Switchman::ActiveRecord::Relation
- Defined in:
- lib/switchman/active_record/relation.rb
Class Method Summary collapse
Instance Method Summary collapse
- #activate(&block) ⇒ Object
- #clone ⇒ Object
- #create(&block) ⇒ Object
- #create!(&block) ⇒ Object
- #explain ⇒ Object
- #find_ids_in_ranges(options = {}) ⇒ Object
- #initialize ⇒ Object
- #merge ⇒ Object
- #new(&block) ⇒ Object
- #records ⇒ Object
- #to_sql ⇒ Object
Class Method Details
.prepended(klass) ⇒ Object
6 7 8 |
# File 'lib/switchman/active_record/relation.rb', line 6 def self.prepended(klass) klass::SINGLE_VALUE_METHODS.concat [ :shard, :shard_source ] end |
Instance Method Details
#activate(&block) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/switchman/active_record/relation.rb', line 100 def activate(&block) shards = all_shards if (Array === shards && shards.length == 1) if shards.first == DefaultShard || shards.first == Shard.current(klass.shard_category) yield(self, shards.first) else shards.first.activate(klass.shard_category) { yield(self, shards.first) } end else # TODO: implement local limit to avoid querying extra shards Shard.with_each_shard(shards, [klass.shard_category]) do shard(Shard.current(klass.shard_category), :to_a).activate(&block) end end end |
#clone ⇒ Object
16 17 18 19 20 |
# File 'lib/switchman/active_record/relation.rb', line 16 def clone result = super result.shard_value = Shard.current(klass ? klass.shard_category : :primary) unless shard_value result end |
#create(&block) ⇒ Object
35 36 37 |
# File 'lib/switchman/active_record/relation.rb', line 35 def create(*, &block) primary_shard.activate(klass.shard_category) { super } end |
#create!(&block) ⇒ Object
39 40 41 |
# File 'lib/switchman/active_record/relation.rb', line 39 def create!(*, &block) primary_shard.activate(klass.shard_category) { super } end |
#explain ⇒ Object
47 48 49 |
# File 'lib/switchman/active_record/relation.rb', line 47 def explain self.activate { |relation| relation.call_super(:explain, Relation) } end |
#find_ids_in_ranges(options = {}) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/switchman/active_record/relation.rb', line 72 def find_ids_in_ranges( = {}) is_integer = columns_hash[primary_key.to_s].type == :integer loose_mode = [:loose] && is_integer # loose_mode: if we don't care about getting exactly batch_size ids in between # don't get the max - just get the min and add batch_size so we get that many _at most_ values = loose_mode ? "MIN(id)" : "MIN(id), MAX(id)" batch_size = [:batch_size].try(:to_i) || 1000 quoted_primary_key = "#{klass.connection.quote_local_table_name(table_name)}.#{klass.connection.quote_column_name(primary_key)}" as_id = " AS id" unless primary_key == 'id' subquery_scope = except(:select).select("#{quoted_primary_key}#{as_id}").reorder(primary_key.to_sym).limit(loose_mode ? 1 : batch_size) subquery_scope = subquery_scope.where("#{quoted_primary_key} <= ?", [:end_at]) if [:end_at] first_subquery_scope = [:start_at] ? subquery_scope.where("#{quoted_primary_key} >= ?", [:start_at]) : subquery_scope ids = connection.select_rows("SELECT #{values} FROM (#{first_subquery_scope.to_sql}) AS subquery").first while ids.first.present? ids.map!(&:to_i) if is_integer ids << ids.first + batch_size if loose_mode yield(*ids) last_value = ids.last next_subquery_scope = subquery_scope.where(["#{quoted_primary_key}>?", last_value]) ids = connection.select_rows("SELECT #{values} FROM (#{next_subquery_scope.to_sql}) AS subquery").first end end |
#initialize ⇒ Object
10 11 12 13 14 |
# File 'lib/switchman/active_record/relation.rb', line 10 def initialize(*, **) super self.shard_value = Shard.current(klass ? klass.shard_category : :primary) unless shard_value self.shard_source_value = :implicit unless shard_source_value end |
#merge ⇒ Object
22 23 24 25 26 27 28 29 |
# File 'lib/switchman/active_record/relation.rb', line 22 def merge(*) relation = super if relation.shard_value != self.shard_value && relation.shard_source_value == :implicit relation.shard_value = self.shard_value relation.shard_source_value = self.shard_source_value end relation end |
#new(&block) ⇒ Object
31 32 33 |
# File 'lib/switchman/active_record/relation.rb', line 31 def new(*, &block) primary_shard.activate(klass.shard_category) { super } end |
#records ⇒ Object
51 52 53 54 55 56 57 58 59 60 |
# File 'lib/switchman/active_record/relation.rb', line 51 def records return @records if loaded? results = self.activate { |relation| relation.call_super(:records, Relation) } case shard_value when Array, ::ActiveRecord::Relation, ::ActiveRecord::Base @records = results @loaded = true end results end |
#to_sql ⇒ Object
43 44 45 |
# File 'lib/switchman/active_record/relation.rb', line 43 def to_sql primary_shard.activate(klass.shard_category) { super } end |