Module: DbCharmer

Defined in:
lib/db_charmer.rb,
lib/db_charmer/railtie.rb,
lib/db_charmer/version.rb,
lib/db_charmer/sharding.rb,
lib/db_charmer/sharding/method.rb,
lib/db_charmer/connection_proxy.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/with_remapped_databases.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/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/rails2/active_record/master_slave_routing.rb,
lib/db_charmer/rails3/active_record/master_slave_routing.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, Railtie

Constant Summary collapse

@@env =

Try to detect current environment or use development by default

DbCharmer.detect_environment
@@connections_should_exist =

Accessors

true

Class Method Summary collapse

Class Method Details

.connections_should_exist?Boolean

Returns:

  • (Boolean)


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

def self.connections_should_exist?
  !! connections_should_exist
end

.current_controllerObject



2
3
4
# File 'lib/db_charmer/force_slave_reads.rb', line 2

def self.current_controller
  Thread.current[:db_charmer_current_controller]
end

.current_controller=(val) ⇒ Object



6
7
8
# File 'lib/db_charmer/force_slave_reads.rb', line 6

def self.current_controller=(val)
  Thread.current[:db_charmer_current_controller] = val
end

.detect_environmentObject

Returns current environment name based on Rails or Rack environment variables



42
43
44
45
# File 'lib/db_charmer.rb', line 42

def self.detect_environment
  return Rails.env if running_with_rails?
  ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'default'
end

.enable_controller_magic!Object


Extend ActionController to support forcing slave reads



68
69
70
71
# File 'lib/db_charmer.rb', line 68

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

.force_slave_readsObject


Force all reads in a block of code to go to a slave

Raises:

  • (ArgumentError)


45
46
47
48
49
50
51
52
53
54
# File 'lib/db_charmer/force_slave_reads.rb', line 45

def self.force_slave_reads
  raise ArgumentError, "No block given" unless block_given?
  old_forced_slave_reads = self.forced_slave_reads_setting
  begin
    self.forced_slave_reads_setting = true
    yield
  ensure
    self.forced_slave_reads_setting = old_forced_slave_reads
  end
end

.force_slave_reads?Boolean


Returns:

  • (Boolean)


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

def self.force_slave_reads?
  # If global force slave reads is requested, do it
  return true if Thread.current[:db_charmer_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

.forced_slave_reads_settingObject




11
12
13
# File 'lib/db_charmer/force_slave_reads.rb', line 11

def self.forced_slave_reads_setting
  Thread.current[:db_charmer_forced_slave_reads]
end

.forced_slave_reads_setting=(val) ⇒ Object



15
16
17
# File 'lib/db_charmer/force_slave_reads.rb', line 15

def self.forced_slave_reads_setting=(val)
  Thread.current[:db_charmer_forced_slave_reads] = val
end

.hijack_new_classes?Boolean

Returns:

  • (Boolean)


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

def self.hijack_new_classes?
  !! Thread.current[:db_charmer_hijack_new_classes]
end

.loggerObject




61
62
63
64
# File 'lib/db_charmer.rb', line 61

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

.rails2?Boolean

Used in all Rails2-specific places

Returns:

  • (Boolean)


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

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

.rails31?Boolean

Used in all Rails3.1-specific places

Returns:

  • (Boolean)


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

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

.rails324?Boolean

Detect broken Rails version

Returns:

  • (Boolean)


31
32
33
# File 'lib/db_charmer.rb', line 31

def self.rails324?
  ActiveRecord::VERSION::STRING == '3.2.4'
end

.rails3?Boolean


Used in all Rails3-specific places

Returns:

  • (Boolean)


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

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

.running_with_rails?Boolean


Returns true if we’re running within a Rails project

Returns:

  • (Boolean)


37
38
39
# File 'lib/db_charmer.rb', line 37

def self.running_with_rails?
  defined?(Rails) && Rails.respond_to?(:env)
end

.with_controller(controller) ⇒ Object




33
34
35
36
37
38
39
40
41
# File 'lib/db_charmer/force_slave_reads.rb', line 33

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



2
3
4
5
6
7
8
9
10
11
12
13
14
# File 'lib/db_charmer/with_remapped_databases.rb', line 2

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