<commit_before>= multi_db

=====-- This GEM was inspired by <NAME>'s "masochism"-Plugin

multi_db uses a connection proxy, which sends read queries to slave databases,
and all write queries to the master database (Read/Write Split).
Within transactions, while executing ActiveRecord Observers and
within "with_master" blocks (see below), even read queries are sent to the 
master database.

=== Important changes in 0.2.0

* As of this version, <tt>ActiveRecord::Base.connection</tt> does not return the
  connection proxy by default anymore (therefore the jump to 0.2.0). Only models
  inheriting from AR::B return the proxy, unless they are defined as master_models
  (see below). If you want to access the connection proxy from AR::B directly,
  use <tt>ActiveRecord::Base.connection_proxy</tt>.

* This version is the first attempt for thread-safety of this gem. <em>There might
  still be some threading issues left!</em>. So please test your apps thoroughly
  and report any issues you might encounter.

* <tt>CGI::Session::ActiveRecordStore::Session</tt> is now automatically registered
  as a master model.

=== Caveats

* works with activerecord 2.1 and 2.2
* when using Passenger or lightspeed you will probably need to introduce a
  before_filter which checks if the proxy is setup (see the discussion in the
  masochism readme: http://github.com/technoweenie/masochism)

=== Install

  gem sources --add http://gems.github.com # only if you haven't already added github
  gem install schoefmax-multi_db

When using Rails, add this to your environment.rb:

  config.gem 'schoefmax-multi_db', :lib => 'multi_db', :source => 'http://gems.github.com'

=== Setup

In your database.yml, add sections for the slaves, e.g.:

  production: # that would be the master
    adapter: mysql
    database: myapp_production
    username: root
    password: 
    host: localhost

  production_slave_database: # that would be a slave 
    adapter: mysql
    database: myapp_production
    username: root
    password: 
    host: 10.0.0.2

  production_slave_database_2: # another slave
    ...
  production_slave_database_in_india: # yet another one
    ...

*NOTE*: multi_db identifies slave databases by looking for entries of the form
"<tt><environment>_slave_database<_optional_name></tt>". As a (useless) side effect you
get abstract classes named <tt>MultiDb::SlaveDatabaseInIndia</tt> etc.
The advantage of specifying the slaves explicitly, instead of the master, is that
you can use the same configuration file for scripts that don't use multi_db.
Also, when you decide to disable multi_db for some reason, you don't have to 
swap hosts in your <tt>database.yml</tt> from master to slave (which is easy to forget...).

To enable the proxy globally, add this to your environment.rb, or some file in
config/initializers:

  MultiDb::ConnectionProxy.setup!

If you only want to enable it for specific environments, add this to 
the corresponding file in config/environments:

  config.after_initialize do
    MultiDb::ConnectionProxy.setup!
  end

In the development and test environments, you can use identical configurations
for master and slave connections. This can help you finding (some of the) issues
your application might have with a replicated database setup without actually having
one on your development machine.

=== Forcing the master for certain actions

Just add this to your controller:

  around_filter(:only => :foo_action) { |c,a| ActiveRecord::Base.connection_proxy.with_master { a.call } }

=== Forcing the master for certain models

In your environment.rb or an initializer, add this *before* the call to <tt>setup!</tt>:

  MultiDb::ConnectionProxy.master_models = ['CGI::Session::ActiveRecordStore::Session', 'PaymentTransaction', ...]
  MultiDb::ConnectionProxy.setup!

*NOTE*: You cannot safely add more master_models after calling <tt>setup!</tt>.<commit_msg>added docs how to use with Phusion Passenger<commit_after>= multi_db

=====-- This GEM was inspired by Rick Olson's "masochism"-Plugin

multi_db uses a connection proxy, which sends read queries to slave databases,
and all write queries to the master database (Read/Write Split).
Within transactions, while executing ActiveRecord Observers and
within "with_master" blocks (see below), even read queries are sent to the 
master database.

=== Important changes in 0.2.0

* As of this version, <tt>ActiveRecord::Base.connection</tt> does not return the
  connection proxy by default anymore (therefore the jump to 0.2.0). Only models
  inheriting from AR::B return the proxy, unless they are defined as master_models
  (see below). If you want to access the connection proxy from AR::B directly,
  use <tt>ActiveRecord::Base.connection_proxy</tt>.

* This version is the first attempt for thread-safety of this gem. <em>There might
  still be some threading issues left!</em>. So please test your apps thoroughly
  and report any issues you might encounter.

* <tt>CGI::Session::ActiveRecordStore::Session</tt> is now automatically registered
  as a master model.

=== Caveats

* works only with activerecord 2.1, 2.2 and 2.3

=== Install

  gem sources --add http://gems.github.com # only if you haven't already added github
  gem install schoefmax-multi_db

When using Rails, add this to your environment.rb:

  config.gem 'schoefmax-multi_db', :lib => 'multi_db', :source => 'http://gems.github.com'

=== Setup

In your database.yml, add sections for the slaves, e.g.:

  production: # that would be the master
    adapter: mysql
    database: myapp_production
    username: root
    password: 
    host: localhost

  production_slave_database: # that would be a slave 
    adapter: mysql
    database: myapp_production
    username: root
    password: 
    host: 10.0.0.2

  production_slave_database_2: # another slave
    ...
  production_slave_database_in_india: # yet another one
    ...

*NOTE*: multi_db identifies slave databases by looking for entries of the form
"<tt><environment>_slave_database<_optional_name></tt>". As a (useless) side effect you
get abstract classes named <tt>MultiDb::SlaveDatabaseInIndia</tt> etc.
The advantage of specifying the slaves explicitly, instead of the master, is that
you can use the same configuration file for scripts that don't use multi_db.
Also, when you decide to disable multi_db for some reason, you don't have to 
swap hosts in your <tt>database.yml</tt> from master to slave (which is easy to forget...).

To enable the proxy globally, add this to your environment.rb, or some file in
config/initializers:

  MultiDb::ConnectionProxy.setup!

If you only want to enable it for specific environments, add this to 
the corresponding file in config/environments:

  config.after_initialize do
    MultiDb::ConnectionProxy.setup!
  end

In the development and test environments, you can use identical configurations
for master and slave connections. This can help you finding (some of the) issues
your application might have with a replicated database setup without actually having
one on your development machine.

=== Using with Phusion Passenger

With Passengers smart spawning method, child processes forked by the ApplicationSpawner
won't have the connection proxy set up properly.

To make it work, add this to your <tt>environment.rb</tt> or an initializer script
(e.g. <tt>config/initializers/connection_proxy.rb</tt>):

  if defined?(PhusionPassenger)
    PhusionPassenger.on_event(:starting_worker_process) do |forked|
      if forked
        # ... set MultiDb configuration options, if any ...
        MultiDb::ConnectionProxy.setup!
      end
    end
  else # not using passenger (e.g. development/testing)
    # ... set MultiDb configuration options, if any ...
    MultiDb::ConnectionProxy.setup!
  end

Thanks to <NAME> for testing this.

=== Forcing the master for certain actions

Just add this to your controller:

  around_filter(:only => :foo_action) { |c,a| ActiveRecord::Base.connection_proxy.with_master { a.call } }

=== Forcing the master for certain models

In your environment.rb or an initializer, add this *before* the call to <tt>setup!</tt>:

  MultiDb::ConnectionProxy.master_models = ['CGI::Session::ActiveRecordStore::Session', 'PaymentTransaction', ...]
  MultiDb::ConnectionProxy.setup!

*NOTE*: You cannot safely add more master_models after calling <tt>setup!</tt>.
{'fraction_non_alphanumeric': 0.08319347878206665, 'fraction_numerical': 0.004075761208343323, 'mean_word_length': 4.337811900191938, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3158704', 'n_tokens_mistral': 2350, 'n_tokens_neox': 2245, 'n_words': 987}