read_from_slave 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +96 -0
- data/README.textile +114 -0
- data/Rakefile +38 -0
- data/VERSION.yml +4 -0
- data/lib/read_from_slave.rb +151 -0
- data/test/active_record_setup.rb +3 -0
- data/test/helper.rb +96 -0
- data/test/models/course.rb +2 -0
- data/test/read_from_slave_test.rb +45 -0
- data/test/schema/schema.rb +5 -0
- data/test/setup.rb +3 -0
- data/test/test.rb +1 -0
- metadata +73 -0
data/README
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
Read_from_slave
|
2
|
+
|
3
|
+
Read_from_slave for Rails enables database reads from a slave database, while writes continue to go to the master
|
4
|
+
|
5
|
+
Read_from_slave will work with Rails 2.2 and above.
|
6
|
+
|
7
|
+
Installation
|
8
|
+
|
9
|
+
sudo gem install sdsykes-read_from_slave
|
10
|
+
|
11
|
+
Configuration
|
12
|
+
|
13
|
+
In config/environments/production.rb (for instance)
|
14
|
+
|
15
|
+
config.gem "sdsykes-read_from_slave", :lib=>"read_from_slave"
|
16
|
+
|
17
|
+
In config/database.yml
|
18
|
+
|
19
|
+
production:
|
20
|
+
adapter: mysql
|
21
|
+
database: mydatabase
|
22
|
+
username: myuser
|
23
|
+
password: mypassword
|
24
|
+
host: my.main.database.server.com
|
25
|
+
port: 3306
|
26
|
+
|
27
|
+
slave_for_mydatabase:
|
28
|
+
adapter: mysql
|
29
|
+
database: mydatabase
|
30
|
+
username: myuser
|
31
|
+
password: mypassword
|
32
|
+
socket: /var/lib/mysql/mysql.sock
|
33
|
+
|
34
|
+
Just use the regular YAML format to specify your slave database, it could equally well be on
|
35
|
+
another server as the local example given above.
|
36
|
+
|
37
|
+
Phusion Passenger
|
38
|
+
|
39
|
+
Note that if you are using Passenger, you need to make sure that the slave database is reconnected
|
40
|
+
if there is any chance that it was accessed before the spawner forks. This could be because
|
41
|
+
database was accessed during the generation of routes, or perhaps if you are using the has_many_polymorphs
|
42
|
+
gem.
|
43
|
+
|
44
|
+
The safest thing to do is to have something like this in your production.rb or environment.rb:
|
45
|
+
|
46
|
+
PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
47
|
+
if forked
|
48
|
+
# We're in smart spawning mode.
|
49
|
+
ActiveRecord::Base.establish_slave_connections
|
50
|
+
else
|
51
|
+
# We're in conservative spawning mode. We don't need to do anything.
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
Documentation
|
56
|
+
|
57
|
+
http://rdoc.info/projects/sdsykes/read_from_slave
|
58
|
+
|
59
|
+
Tests
|
60
|
+
|
61
|
+
Clone the git repository, and you can run the read_from_slave tests or entire ActiveRecord test suite to prove that read_from_slave works correctly.
|
62
|
+
|
63
|
+
$ rake test
|
64
|
+
...snip..
|
65
|
+
Finished in 0.046365 seconds.
|
66
|
+
|
67
|
+
7 tests, 7 assertions, 0 failures, 0 errors
|
68
|
+
|
69
|
+
$ rake test_with_active_record
|
70
|
+
...snip...
|
71
|
+
Finished in 51.904306 seconds.
|
72
|
+
|
73
|
+
2057 tests, 6685 assertions, 0 failures, 0 errors
|
74
|
+
|
75
|
+
Todo
|
76
|
+
|
77
|
+
* Support a pool of multiple slaves
|
78
|
+
|
79
|
+
References
|
80
|
+
|
81
|
+
"Masochism":http://github.com/technoweenie/masochism/tree/master
|
82
|
+
not thread safe
|
83
|
+
won't work with apps that talk to multiple (master) databases
|
84
|
+
|
85
|
+
"Acts as readonlyable":http://rubyforge.org/projects/acts-as-with-ro/
|
86
|
+
old, not suitable for Rails 2.x
|
87
|
+
|
88
|
+
"master_slave_adapter":http://github.com/mauricio/master_slave_adapter/tree/master
|
89
|
+
similar to read_from_slave, but adapter based approach
|
90
|
+
|
91
|
+
"multi_db":http://github.com/schoefmax/multi_db/tree/master
|
92
|
+
another one, proxy connection approach
|
93
|
+
looks like it won't work with apps that talk to multiple (master) databases
|
94
|
+
more complex than read_from_slave
|
95
|
+
|
96
|
+
(c) 2009 Stephen Sykes
|
data/README.textile
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
h1. Read_from_slave
|
2
|
+
|
3
|
+
h4. Read_from_slave for Rails enables database reads from a slave database, while writes continue to go to the master
|
4
|
+
|
5
|
+
Read_from_slave will work with Rails 2.2 and above.
|
6
|
+
|
7
|
+
h2. Installation
|
8
|
+
|
9
|
+
<pre>
|
10
|
+
<code>
|
11
|
+
sudo gem install sdsykes-read_from_slave
|
12
|
+
</code>
|
13
|
+
</pre>
|
14
|
+
|
15
|
+
h2. Configuration
|
16
|
+
|
17
|
+
In config/environments/production.rb (for instance)
|
18
|
+
|
19
|
+
<pre>
|
20
|
+
<code>
|
21
|
+
config.gem "sdsykes-read_from_slave", :lib=>"read_from_slave"
|
22
|
+
</code>
|
23
|
+
</pre>
|
24
|
+
|
25
|
+
In config/database.yml
|
26
|
+
|
27
|
+
<pre>
|
28
|
+
<code>
|
29
|
+
production:
|
30
|
+
adapter: mysql
|
31
|
+
database: mydatabase
|
32
|
+
username: myuser
|
33
|
+
password: mypassword
|
34
|
+
host: my.main.database.server.com
|
35
|
+
port: 3306
|
36
|
+
|
37
|
+
slave_for_mydatabase:
|
38
|
+
adapter: mysql
|
39
|
+
database: mydatabase
|
40
|
+
username: myuser
|
41
|
+
password: mypassword
|
42
|
+
socket: /var/lib/mysql/mysql.sock
|
43
|
+
</code>
|
44
|
+
</pre>
|
45
|
+
|
46
|
+
Just use the regular YAML format to specify your slave database, it could equally well be on
|
47
|
+
another server as the local example given above.
|
48
|
+
|
49
|
+
h2. Phusion Passenger
|
50
|
+
|
51
|
+
Note that if you are using Passenger, you need to make sure that the slave database is reconnected
|
52
|
+
if there is any chance that it was accessed before the spawner forks. This could be because
|
53
|
+
database was accessed during the generation of routes, or perhaps if you are using the has_many_polymorphs
|
54
|
+
gem.
|
55
|
+
|
56
|
+
The safest thing to do is to have something like this in your production.rb or environment.rb:
|
57
|
+
|
58
|
+
<pre>
|
59
|
+
<code>
|
60
|
+
PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
61
|
+
if forked
|
62
|
+
# We're in smart spawning mode.
|
63
|
+
ActiveRecord::Base.establish_slave_connections
|
64
|
+
else
|
65
|
+
# We're in conservative spawning mode. We don't need to do anything.
|
66
|
+
end
|
67
|
+
end
|
68
|
+
</code>
|
69
|
+
</pre>
|
70
|
+
|
71
|
+
h2. Documentation
|
72
|
+
|
73
|
+
"http://rdoc.info/projects/sdsykes/read_from_slave":http://rdoc.info/projects/sdsykes/read_from_slave
|
74
|
+
|
75
|
+
h2. Tests
|
76
|
+
|
77
|
+
Clone the git repository, and you can run the read_from_slave tests or entire ActiveRecord test suite to prove that read_from_slave works correctly.
|
78
|
+
|
79
|
+
<pre>
|
80
|
+
<code>
|
81
|
+
$ rake test
|
82
|
+
...snip..
|
83
|
+
Finished in 0.046365 seconds.
|
84
|
+
|
85
|
+
7 tests, 7 assertions, 0 failures, 0 errors
|
86
|
+
|
87
|
+
$ rake test_with_active_record
|
88
|
+
...snip...
|
89
|
+
Finished in 51.904306 seconds.
|
90
|
+
|
91
|
+
2057 tests, 6685 assertions, 0 failures, 0 errors
|
92
|
+
</code>
|
93
|
+
</pre>
|
94
|
+
|
95
|
+
h2. Todo
|
96
|
+
|
97
|
+
* Support a pool of multiple slaves
|
98
|
+
|
99
|
+
h2. References
|
100
|
+
|
101
|
+
* "Masochism":http://github.com/technoweenie/masochism/tree/master
|
102
|
+
** not thread safe
|
103
|
+
** won't work with apps that talk to multiple (master) databases
|
104
|
+
* "Acts as readonlyable":http://rubyforge.org/projects/acts-as-with-ro/
|
105
|
+
** old, not suitable for Rails 2.x
|
106
|
+
* "master_slave_adapter":http://github.com/mauricio/master_slave_adapter/tree/master
|
107
|
+
** similar to read_from_slave, but adapter based approach
|
108
|
+
* "multi_db":http://github.com/schoefmax/multi_db/tree/master
|
109
|
+
** another one, proxy connection approach
|
110
|
+
** looks like it won't work with apps that talk to multiple (master) databases
|
111
|
+
** more complex than read_from_slave
|
112
|
+
|
113
|
+
|
114
|
+
(c) 2009 Stephen Sykes
|
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'test/helper'
|
4
|
+
|
5
|
+
task :default => [:test_read_from_slave]
|
6
|
+
|
7
|
+
task :test => :default
|
8
|
+
|
9
|
+
Rake::TestTask.new(:test_with_active_record) do |t|
|
10
|
+
t.libs << ReadFromSlave::ActiveRecordTest::AR_TEST_SUITE
|
11
|
+
t.libs << ReadFromSlave::ActiveRecordTest.connection
|
12
|
+
t.test_files = ReadFromSlave::ActiveRecordTest.test_files
|
13
|
+
t.ruby_opts = ["-r #{File.join(File.dirname(__FILE__), 'test', 'active_record_setup')}"]
|
14
|
+
t.verbose = true
|
15
|
+
end
|
16
|
+
|
17
|
+
Rake::TestTask.new(:test_read_from_slave) do |t|
|
18
|
+
t.libs << 'lib'
|
19
|
+
t.test_files = ReadFromSlave::Test.test_files
|
20
|
+
t.verbose = true
|
21
|
+
end
|
22
|
+
|
23
|
+
begin
|
24
|
+
require 'jeweler'
|
25
|
+
Jeweler::Tasks.new do |s|
|
26
|
+
s.name = "read_from_slave"
|
27
|
+
s.summary = "Read_from_slave - Utilise your slave databases with rails"
|
28
|
+
s.email = "sdsykes@gmail.com"
|
29
|
+
s.homepage = "http://github.com/sdsykes/read_from_slave"
|
30
|
+
s.description = "Read_from_slave for Rails enables database reads from a slave database, while writes continue to go to the master"
|
31
|
+
s.authors = ["Stephen Sykes"]
|
32
|
+
s.files = FileList["[A-Z]*", "{lib,test}/**/*"]
|
33
|
+
end
|
34
|
+
Jeweler::GemcutterTasks.new
|
35
|
+
rescue LoadError
|
36
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://
|
37
|
+
gems.github.com"
|
38
|
+
end
|
data/VERSION.yml
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
# Read_from_slave for Rails enables database reads from a slave database, while writes continue
|
2
|
+
# to go to the master
|
3
|
+
# To use read_from_slave you must install the gem, configure the gem in your environment file,
|
4
|
+
# and setup your database.yml file with an entry for your slave database.
|
5
|
+
#
|
6
|
+
# === Configuration
|
7
|
+
# In config/environments/production.rb (for instance)
|
8
|
+
#
|
9
|
+
# config.gem "sdsykes-read_from_slave", :lib=>"read_from_slave"
|
10
|
+
#
|
11
|
+
# In config/database.yml
|
12
|
+
#
|
13
|
+
# production:
|
14
|
+
# adapter: mysql
|
15
|
+
# database: mydatabase
|
16
|
+
# username: myuser
|
17
|
+
# password: mypassword
|
18
|
+
# host: my.main.database.server.com
|
19
|
+
# port: 3306
|
20
|
+
#
|
21
|
+
# slave_for_mydatabase:
|
22
|
+
# adapter: mysql
|
23
|
+
# database: mydatabase
|
24
|
+
# username: myuser
|
25
|
+
# password: mypassword
|
26
|
+
# socket: /var/lib/mysql/mysql.sock
|
27
|
+
#
|
28
|
+
# Note that if you have multiple databases you can also configure multiple slaves - use the
|
29
|
+
# database name after slave_for_ in the configuration.
|
30
|
+
#
|
31
|
+
# === References
|
32
|
+
# * "Masochism":http://github.com/technoweenie/masochism/tree/master
|
33
|
+
# ** not thread safe
|
34
|
+
# ** won't work with apps that talk to multiple (master) databases
|
35
|
+
# * "Acts as readonlyable":http://rubyforge.org/projects/acts-as-with-ro/
|
36
|
+
# ** old, not suitable for Rails 2.x
|
37
|
+
# * "master_slave_adapter":http://github.com/mauricio/master_slave_adapter/tree/master
|
38
|
+
# ** similar to read_from_slave, but adapter based approach
|
39
|
+
# * "multi_db":http://github.com/schoefmax/multi_db/tree/master
|
40
|
+
# ** another one, proxy connection approach
|
41
|
+
# ** looks like it won't work with apps that talk to multiple (master) databases
|
42
|
+
# ** more complex than read_from_slave
|
43
|
+
#
|
44
|
+
module ReadFromSlave
|
45
|
+
class << self
|
46
|
+
def install!
|
47
|
+
base = ActiveRecord::Base
|
48
|
+
base.send(:include, InstanceMethods)
|
49
|
+
base.alias_method_chain :reload, :read_from_slave
|
50
|
+
base.extend(SingletonMethods)
|
51
|
+
base.class_eval do
|
52
|
+
class << self
|
53
|
+
alias_method_chain :find_by_sql, :read_from_slave
|
54
|
+
alias_method_chain :connection, :read_from_slave
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module InstanceMethods
|
61
|
+
def reload_with_read_from_slave(options = nil)
|
62
|
+
Thread.current[:read_from_slave] = :reload
|
63
|
+
reload_without_read_from_slave(options)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
module SingletonMethods
|
68
|
+
|
69
|
+
@@slave_models = {}
|
70
|
+
|
71
|
+
def find_by_sql_with_read_from_slave(sql)
|
72
|
+
Thread.current[:read_from_slave] = (Thread.current[:read_from_slave] != :reload)
|
73
|
+
find_by_sql_without_read_from_slave(sql)
|
74
|
+
ensure
|
75
|
+
Thread.current[:read_from_slave] = false
|
76
|
+
end
|
77
|
+
|
78
|
+
def connection_with_read_from_slave
|
79
|
+
normal_connection = connection_without_read_from_slave
|
80
|
+
if Thread.current[:read_from_slave] && normal_connection.open_transactions == 0
|
81
|
+
Thread.current[:read_from_slave_uses] = :slave # for testing use
|
82
|
+
slave_connection
|
83
|
+
else
|
84
|
+
Thread.current[:read_from_slave_uses] = :master
|
85
|
+
normal_connection
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Returns a connection to the slave database, or to the regular database if
|
90
|
+
# no slave is configured
|
91
|
+
#
|
92
|
+
def slave_connection
|
93
|
+
(@slave_model || slave_model).connection_without_read_from_slave
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
# Returns an AR model class that has a connection to the appropriate slave db
|
98
|
+
#
|
99
|
+
def slave_model
|
100
|
+
db_name = master_database_name
|
101
|
+
if slave_config_for(db_name)
|
102
|
+
unless @@slave_models[db_name]
|
103
|
+
slave_model_name = "ReadFromSlaveFor_#{db_name}"
|
104
|
+
@@slave_models[db_name] = eval %{
|
105
|
+
class #{slave_model_name} < ActiveRecord::Base
|
106
|
+
self.abstract_class = true
|
107
|
+
establish_slave_connection_for('#{db_name}')
|
108
|
+
end
|
109
|
+
#{slave_model_name}
|
110
|
+
}
|
111
|
+
end
|
112
|
+
@slave_model = @@slave_models[db_name]
|
113
|
+
else
|
114
|
+
@slave_model = self
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Returns the name of the database in use, as given in the database.yml file
|
119
|
+
#
|
120
|
+
def master_database_name
|
121
|
+
connection_without_read_from_slave.instance_variable_get(:@config)[:database]
|
122
|
+
end
|
123
|
+
|
124
|
+
# Returns the config for the associated slave database for this master,
|
125
|
+
# as given in the database.yml file
|
126
|
+
#
|
127
|
+
def slave_config_for(master)
|
128
|
+
configurations["slave_for_#{master}"]
|
129
|
+
end
|
130
|
+
|
131
|
+
# Establishes a connection to the slave database that is configured for
|
132
|
+
# the database name provided
|
133
|
+
#
|
134
|
+
def establish_slave_connection_for(master)
|
135
|
+
conn_spec = slave_config_for(master)
|
136
|
+
establish_connection(conn_spec) if conn_spec
|
137
|
+
end
|
138
|
+
|
139
|
+
# Re-establishes connections to all the slave databases that
|
140
|
+
# have been used so far. Use this in your
|
141
|
+
# PhusionPassenger.on_event(:starting_worker_process) block if required.
|
142
|
+
#
|
143
|
+
def establish_slave_connections
|
144
|
+
@@slave_models.each do |db_name, model|
|
145
|
+
model.establish_slave_connection_for(db_name)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
ReadFromSlave.install!
|
data/test/helper.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'setup')
|
2
|
+
require 'active_support/test_case'
|
3
|
+
|
4
|
+
module ReadFromSlave
|
5
|
+
class Test
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def setup
|
9
|
+
setup_constants
|
10
|
+
make_sqlite_config
|
11
|
+
make_sqlite_connection
|
12
|
+
load_models
|
13
|
+
load(SCHEMA_ROOT + "/schema.rb")
|
14
|
+
require 'test/unit'
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_files
|
18
|
+
glob("#{File.dirname(__FILE__)}/**/*_test.rb")
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_model_files
|
22
|
+
%w{course}
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def setup_constants
|
28
|
+
set_constant('TEST_ROOT') {File.expand_path(File.dirname(__FILE__))}
|
29
|
+
set_constant('SCHEMA_ROOT') {TEST_ROOT + "/schema"}
|
30
|
+
end
|
31
|
+
|
32
|
+
def make_sqlite_config
|
33
|
+
ActiveRecord::Base.configurations = {
|
34
|
+
'rfs' => {
|
35
|
+
:adapter => 'sqlite3',
|
36
|
+
:database => 'test_db',
|
37
|
+
:timeout => 5000
|
38
|
+
},
|
39
|
+
'slave_for_test_db' => {
|
40
|
+
:adapter => 'sqlite3',
|
41
|
+
:database => 'test_db',
|
42
|
+
:timeout => 5000
|
43
|
+
}
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def load_models
|
48
|
+
test_model_files.each {|f| require File.join(File.dirname(__FILE__), "models", f)}
|
49
|
+
end
|
50
|
+
|
51
|
+
def make_sqlite_connection
|
52
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['rfs'])
|
53
|
+
end
|
54
|
+
|
55
|
+
def set_constant(constant)
|
56
|
+
Object.const_set(constant, yield) unless Object.const_defined?(constant)
|
57
|
+
end
|
58
|
+
|
59
|
+
def glob(pattern)
|
60
|
+
Dir.glob(pattern)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class ActiveRecordTest < Test
|
66
|
+
class << self
|
67
|
+
def setup
|
68
|
+
setup_constants
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_files
|
72
|
+
glob("#{AR_TEST_SUITE}/cases/**/*_test.rb").sort
|
73
|
+
end
|
74
|
+
|
75
|
+
def connection
|
76
|
+
File.join(AR_TEST_SUITE, 'connections', 'native_mysql')
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def setup_constants
|
82
|
+
set_constant('MYSQL_DB_USER') {'rails'}
|
83
|
+
set_constant('AR_TEST_SUITE') {find_active_record_test_suite}
|
84
|
+
end
|
85
|
+
|
86
|
+
def find_active_record_test_suite
|
87
|
+
ts = ($:).grep(/activerecord/).last.split('/')
|
88
|
+
ts.pop
|
89
|
+
ts << 'test'
|
90
|
+
ts.join('/')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
AR_TEST_SUITE = find_active_record_test_suite
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "helper")
|
2
|
+
|
3
|
+
ReadFromSlave::Test.setup
|
4
|
+
|
5
|
+
class ReadFromSlaveTest < ActiveSupport::TestCase
|
6
|
+
test "slave connection should be different from normal connection" do
|
7
|
+
assert_not_equal Course.connection_without_read_from_slave, Course.slave_connection
|
8
|
+
end
|
9
|
+
|
10
|
+
test "should be able to write and read from database" do
|
11
|
+
Course.create(:name=>"Saw playing")
|
12
|
+
x = Course.find(:first)
|
13
|
+
assert_equal "Saw playing", x.name
|
14
|
+
end
|
15
|
+
|
16
|
+
test "should write to master" do
|
17
|
+
Course.create(:name=>"Saw playing")
|
18
|
+
assert_equal :master, Thread.current[:read_from_slave_uses]
|
19
|
+
end
|
20
|
+
|
21
|
+
test "should read from slave" do
|
22
|
+
Course.create(:name=>"Saw playing")
|
23
|
+
x = Course.find(:first)
|
24
|
+
assert_equal :slave, Thread.current[:read_from_slave_uses]
|
25
|
+
end
|
26
|
+
|
27
|
+
test "should reload from master" do
|
28
|
+
Course.create(:name=>"Saw playing")
|
29
|
+
x = Course.find(:first)
|
30
|
+
x.reload
|
31
|
+
assert_equal :master, Thread.current[:read_from_slave_uses]
|
32
|
+
end
|
33
|
+
|
34
|
+
test "should get new slave connection when calling establish_slave_connections" do
|
35
|
+
conn = Course.slave_connection
|
36
|
+
ActiveRecord::Base.establish_slave_connections
|
37
|
+
assert_not_equal conn, Course.slave_connection
|
38
|
+
end
|
39
|
+
|
40
|
+
test "should not get new master connection when calling establish_slave_connections" do
|
41
|
+
conn = Course.connection_without_read_from_slave
|
42
|
+
ActiveRecord::Base.establish_slave_connections
|
43
|
+
assert_equal conn, Course.connection_without_read_from_slave
|
44
|
+
end
|
45
|
+
end
|
data/test/setup.rb
ADDED
data/test/test.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# todo
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: read_from_slave
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stephen Sykes
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-10 00:00:00 +03:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Read_from_slave for Rails enables database reads from a slave database, while writes continue to go to the master
|
17
|
+
email: sdsykes@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
- README.textile
|
25
|
+
files:
|
26
|
+
- README
|
27
|
+
- README.textile
|
28
|
+
- Rakefile
|
29
|
+
- VERSION.yml
|
30
|
+
- lib/read_from_slave.rb
|
31
|
+
- test/active_record_setup.rb
|
32
|
+
- test/helper.rb
|
33
|
+
- test/models/course.rb
|
34
|
+
- test/read_from_slave_test.rb
|
35
|
+
- test/schema/schema.rb
|
36
|
+
- test/setup.rb
|
37
|
+
- test/test.rb
|
38
|
+
has_rdoc: true
|
39
|
+
homepage: http://github.com/sdsykes/read_from_slave
|
40
|
+
licenses: []
|
41
|
+
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options:
|
44
|
+
- --charset=UTF-8
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.3.5
|
63
|
+
signing_key:
|
64
|
+
specification_version: 3
|
65
|
+
summary: Read_from_slave - Utilise your slave databases with rails
|
66
|
+
test_files:
|
67
|
+
- test/active_record_setup.rb
|
68
|
+
- test/helper.rb
|
69
|
+
- test/models/course.rb
|
70
|
+
- test/read_from_slave_test.rb
|
71
|
+
- test/schema/schema.rb
|
72
|
+
- test/setup.rb
|
73
|
+
- test/test.rb
|