Module: DbCharmer

Defined in:
lib/db_charmer/connection_proxy.rb,
lib/db_charmer.rb,
lib/db_charmer/version.rb,
lib/db_charmer/sharding.rb,
lib/db_charmer/sharding/method.rb,
lib/db_charmer/force_slave_reads.rb,
lib/db_charmer/connection_factory.rb,
lib/db_charmer/sharding/connection.rb,
lib/db_charmer/sharding/method/range.rb,
lib/db_charmer/active_record/db_magic.rb,
lib/db_charmer/active_record/sharding.rb,
lib/db_charmer/sharding/method/hash_map.rb,
lib/db_charmer/sharding/stub_connection.rb,
lib/db_charmer/active_record/multi_db_proxy.rb,
lib/db_charmer/sharding/method/db_block_map.rb,
lib/db_charmer/active_record/class_attributes.rb,
lib/db_charmer/active_record/association_preload.rb,
lib/db_charmer/active_record/connection_switching.rb,
lib/db_charmer/sharding/method/db_block_group_map.rb,
lib/db_charmer/action_controller/force_slave_reads.rb,
lib/db_charmer/rails3/active_record/log_subscriber.rb,
lib/db_charmer/sharding/method/db_block_schema_map.rb,
lib/db_charmer/rails3/active_record/relation_method.rb,
lib/db_charmer/rails2/abstract_adapter/log_formatting.rb,
lib/db_charmer/rails3/abstract_adapter/connection_name.rb,
lib/db_charmer/sharding/method/db_block_group_map_base.rb,
lib/db_charmer/rails2/active_record/master_slave_routing.rb,
lib/db_charmer/rails3/active_record/master_slave_routing.rb,
lib/db_charmer/rails3/active_record/relation/arel_engine.rb,
lib/db_charmer/active_record/migration/multi_db_migrations.rb,
lib/db_charmer/rails31/active_record/preloader/association.rb,
lib/db_charmer/rails2/active_record/named_scope/scope_proxy.rb,
lib/db_charmer/rails3/active_record/relation/connection_routing.rb,
lib/db_charmer/rails31/active_record/migration/command_recorder.rb,
lib/db_charmer/rails31/active_record/preloader/has_and_belongs_to_many.rb

Overview

This is a more sophisticated sharding method based on a two layer database-backed blocks map that holds block-shard associations. Record blocks are mapped to tablegroups and groups are mapped to shards.

It automatically creates new blocks for new keys and assigns them to existing groups. Warning: make sure to create at least one shard and one group before inserting any records.

Defined Under Namespace

Modules: AbstractAdapter, ActionController, ActiveRecord, ConnectionFactory, Sharding, Version Classes: ConnectionProxy

Constant Summary collapse

@@connections_should_exist =

Accessors

true
@@env =
'development'
@@current_controller =
nil
@@forced_slave_reads =
false

Class Method Summary collapse

Class Method Details

.connections_should_exist?Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/db_charmer.rb', line 47

def self.connections_should_exist?
  !! connections_should_exist
end

.enable_controller_magic!Object

Extend ActionController to support forcing slave reads



52
53
54
55
# File 'lib/db_charmer.rb', line 52

def self.enable_controller_magic!
  ::ActionController::Base.extend(DbCharmer::ActionController::ForceSlaveReads::ClassMethods)
  ::ActionController::Base.send(:include, DbCharmer::ActionController::ForceSlaveReads::InstanceMethods)
end

.force_slave_readsObject



29
30
31
32
33
34
35
# File 'lib/db_charmer/force_slave_reads.rb', line 29

def self.force_slave_reads
  raise ArgumentError, "No block given" unless block_given?
  @@forced_slave_reads = true
  yield
ensure
  @@forced_slave_reads = false
end

.force_slave_reads?Boolean

Returns:

  • (Boolean)


7
8
9
10
11
12
13
14
15
16
17
# File 'lib/db_charmer/force_slave_reads.rb', line 7

def self.force_slave_reads?
  # If global force slave reads is requested, do it
  return @@forced_slave_reads if @@forced_slave_reads

  # If not, try to use current controller to decide on this
  return false unless current_controller.respond_to?(:force_slave_reads?)

  slave_reads = current_controller.force_slave_reads?
  logger.debug("Using controller to figure out if slave reads should be forced: #{slave_reads}")
  return slave_reads
end

.hijack_new_classes?Boolean

Returns:

  • (Boolean)


76
77
78
# File 'lib/db_charmer.rb', line 76

def self.hijack_new_classes?
  @@hijack_new_classes
end

.loggerObject



57
58
59
60
# File 'lib/db_charmer.rb', line 57

def self.logger
  return Rails.logger if defined?(Rails)
  @logger ||= Logger.new(STDERR)
end

.rails2?Boolean

Used in all Rails2-specific places

Returns:

  • (Boolean)


27
28
29
# File 'lib/db_charmer.rb', line 27

def self.rails2?
  ::ActiveRecord::VERSION::MAJOR == 2
end

.rails31?Boolean

Used in all Rails3.1-specific places

Returns:

  • (Boolean)


22
23
24
# File 'lib/db_charmer.rb', line 22

def self.rails31?
  rails3? && ::ActiveRecord::VERSION::MINOR >= 1
end

.rails3?Boolean

Used in all Rails3-specific places

Returns:

  • (Boolean)


17
18
19
# File 'lib/db_charmer.rb', line 17

def self.rails3?
  ::ActiveRecord::VERSION::MAJOR > 2
end

.with_controller(controller) ⇒ Object



19
20
21
22
23
24
25
26
27
# File 'lib/db_charmer/force_slave_reads.rb', line 19

def self.with_controller(controller)
  raise ArgumentError, "No block given" unless block_given?
  logger.debug("Setting current controller for db_charmer: #{controller.class.name}")
  self.current_controller = controller
  yield
ensure
  logger.debug('Clearing current controller for db_charmer')
  self.current_controller = nil
end

.with_remapped_databases(mappings, &proc) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/db_charmer.rb', line 62

def self.with_remapped_databases(mappings, &proc)
  old_mappings = ::ActiveRecord::Base.db_charmer_database_remappings
  begin
    ::ActiveRecord::Base.db_charmer_database_remappings = mappings
    if mappings[:master] || mappings['master']
      with_all_hijacked(&proc)
    else
      proc.call
    end
  ensure
    ::ActiveRecord::Base.db_charmer_database_remappings = old_mappings
  end
end