Module: Switchman::ActiveRecord::Relation

Defined in:
lib/switchman/active_record/relation.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(klass) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
# File 'lib/switchman/active_record/relation.rb', line 4

def self.included(klass)
  klass::SINGLE_VALUE_METHODS.concat [ :shard, :shard_source ]

  %w{exec_queries update_all delete_all}.each do |method|
    klass.alias_method_chain(method, :deshackles)
  end

  %w{initialize clone explain to_a update_all delete_all new create create!}.each do |method|
    klass.alias_method_chain(method, :sharding)
  end
end

Instance Method Details

#activate(&block) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/switchman/active_record/relation.rb', line 93

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_with_shardingObject



22
23
24
25
26
# File 'lib/switchman/active_record/relation.rb', line 22

def clone_with_sharding
  result = clone_without_sharding
  result.shard_value = Shard.current(klass.respond_to?(:shard_category) ? klass.shard_category : :default) unless shard_value
  result
end

#create_with_sharding(*args, &block) ⇒ Object



41
42
43
# File 'lib/switchman/active_record/relation.rb', line 41

def create_with_sharding(*args, &block)
  primary_shard.activate(klass.shard_category) { create_without_sharding(*args, &block) }
end

#create_with_sharding!(*args, &block) ⇒ Object



45
46
47
# File 'lib/switchman/active_record/relation.rb', line 45

def create_with_sharding!(*args, &block)
  primary_shard.activate(klass.shard_category) { create_without_sharding!(*args, &block) }
end

#exec_queries_with_deshackles(*args) ⇒ Object



49
50
51
52
53
54
55
56
57
# File 'lib/switchman/active_record/relation.rb', line 49

def exec_queries_with_deshackles(*args)
  if self.lock_value
    db = Shard.current(shard_category).database_server
    if ::Shackles.environment != db.shackles_environment
      return db.unshackle { exec_queries_without_deshackles(*args) }
    end
  end
  exec_queries_without_deshackles(*args)
end

#explain_with_shardingObject



59
60
61
# File 'lib/switchman/active_record/relation.rb', line 59

def explain_with_sharding
  self.activate { |relation| relation.send(:explain_without_sharding) }
end

#initialize_with_sharding(*args) ⇒ Object



16
17
18
19
20
# File 'lib/switchman/active_record/relation.rb', line 16

def initialize_with_sharding(*args)
  initialize_without_sharding(*args)
  self.shard_value = Shard.current(klass.respond_to?(:shard_category) ? klass.shard_category : :default) unless shard_value
  self.shard_source_value = :implicit unless shard_source_value
end

#merge(*args) ⇒ Object



28
29
30
31
32
33
34
35
# File 'lib/switchman/active_record/relation.rb', line 28

def merge(*args)
  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_with_sharding(*args, &block) ⇒ Object



37
38
39
# File 'lib/switchman/active_record/relation.rb', line 37

def new_with_sharding(*args, &block)
  primary_shard.activate(klass.shard_category) { new_without_sharding(*args, &block) }
end

#to_a_with_shardingObject



63
64
65
66
67
68
69
70
71
72
# File 'lib/switchman/active_record/relation.rb', line 63

def to_a_with_sharding
  return @records if loaded?
  results = self.activate { |relation| relation.send(:to_a_without_sharding) }
  case shard_value
  when Array, ::ActiveRecord::Relation, ::ActiveRecord::Base
    @records = results
    @loaded = true
  end
  results
end