seamless_database_pool 1.0.9 → 1.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +2 -0
- data/Rakefile +3 -0
- data/lib/active_record/connection_adapters/seamless_database_pool_adapter.rb +64 -45
- data/lib/seamless_database_pool.rb +20 -5
- data/spec/connection_adapters_spec.rb +26 -25
- data/spec/test_adapter/active_record/connection_adapters/read_only_adapter.rb +18 -5
- data/spec/test_model.rb +3 -3
- metadata +45 -28
data/README.rdoc
CHANGED
@@ -66,6 +66,8 @@ In this configuration, the master connection will be a mysql connection to maste
|
|
66
66
|
|
67
67
|
The read pool will use three mysql connections to master-db, read-db-1, and read-db-2. The master connection will use a different port, username, password for the connection. The read connections will use the same values. Further, the connection read-db-1 will get half the traffic as the other two connections, so presumably it's on a more powerful box.
|
68
68
|
|
69
|
+
You must use compatible database adapters for both the master and the read connections. For example, you cannot use an Oracle server as your master and PostgreSQL servers as you read slaves.
|
70
|
+
|
69
71
|
= Using the read pool
|
70
72
|
|
71
73
|
By default, the master connection will be used for everything. This is not terribly useful, so you should really specify a method of using the read pool for the actions that need it. Read connections will only be used for select statements against the database.
|
data/Rakefile
CHANGED
@@ -75,6 +75,9 @@ begin
|
|
75
75
|
gem.add_dependency('activerecord', '>= 2.2.2')
|
76
76
|
gem.add_development_dependency('rspec', '>= 2.0')
|
77
77
|
gem.add_development_dependency('jeweler')
|
78
|
+
gem.add_development_dependency('sqlite3')
|
79
|
+
gem.add_development_dependency('mysql')
|
80
|
+
gem.add_development_dependency('pg')
|
78
81
|
end
|
79
82
|
|
80
83
|
Jeweler::GemcutterTasks.new
|
@@ -16,7 +16,7 @@ module ActiveRecord
|
|
16
16
|
master_connection.class.send(:include, SeamlessDatabasePool::ConnectTimeout) unless master_connection.class.include?(SeamlessDatabasePool::ConnectTimeout)
|
17
17
|
master_connection.connect_timeout = master_config[:connect_timeout]
|
18
18
|
pool_weights[master_connection] = master_config[:pool_weight].to_i if master_config[:pool_weight].to_i > 0
|
19
|
-
|
19
|
+
|
20
20
|
read_connections = []
|
21
21
|
config[:read_pool].each do |read_config|
|
22
22
|
read_config = default_config.merge(read_config).with_indifferent_access
|
@@ -30,6 +30,7 @@ module ActiveRecord
|
|
30
30
|
read_connections << conn
|
31
31
|
pool_weights[conn] = read_config[:pool_weight]
|
32
32
|
rescue Exception => e
|
33
|
+
raise e # TODO remove
|
33
34
|
if logger
|
34
35
|
logger.error("Error connecting to read connection #{read_config.inspect}")
|
35
36
|
logger.error(e)
|
@@ -48,7 +49,7 @@ module ActiveRecord
|
|
48
49
|
return klass.new(nil, logger, master_connection, read_connections, pool_weights)
|
49
50
|
end
|
50
51
|
|
51
|
-
def establish_adapter
|
52
|
+
def establish_adapter(adapter)
|
52
53
|
raise AdapterNotSpecified.new("database configuration does not specify adapter") unless adapter
|
53
54
|
raise AdapterNotFound.new("database pool must specify adapters") if adapter == 'seamless_database_pool'
|
54
55
|
|
@@ -77,7 +78,7 @@ module ActiveRecord
|
|
77
78
|
end
|
78
79
|
|
79
80
|
# Force reload to use the master connection since it's probably being called for a reason.
|
80
|
-
def reload_with_seamless_database_pool
|
81
|
+
def reload_with_seamless_database_pool(*args)
|
81
82
|
SeamlessDatabasePool.use_master_connection do
|
82
83
|
reload_without_seamless_database_pool(*args)
|
83
84
|
end
|
@@ -92,50 +93,60 @@ module ActiveRecord
|
|
92
93
|
|
93
94
|
attr_reader :read_connections, :master_connection
|
94
95
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
96
|
+
class << self
|
97
|
+
# Create an anonymous class that extends this one and proxies methods to the pool connections.
|
98
|
+
def adapter_class(master_connection)
|
99
|
+
# Define methods to proxy to the appropriate pool
|
100
|
+
read_only_methods = [:select_one, :select_all, :select_value, :select_values, :select, :select_rows, :execute, :tables, :columns]
|
101
|
+
master_methods = []
|
102
|
+
master_connection_classes = [AbstractAdapter, Quoting, DatabaseStatements, SchemaStatements]
|
103
|
+
master_connection_classes << DatabaseLimits if const_defined?(:DatabaseLimits)
|
104
|
+
master_connection_class = master_connection.class
|
105
|
+
while ![Object, AbstractAdapter].include?(master_connection_class) do
|
106
|
+
master_connection_classes << master_connection_class
|
107
|
+
master_connection_class = master_connection_class.superclass
|
108
|
+
end
|
109
|
+
master_connection_classes.each do |connection_class|
|
110
|
+
master_methods.concat(connection_class.public_instance_methods(false))
|
111
|
+
master_methods.concat(connection_class.protected_instance_methods(false))
|
112
|
+
end
|
113
|
+
master_methods.uniq!
|
114
|
+
master_methods -= public_instance_methods(false) + protected_instance_methods(false) + private_instance_methods(false)
|
115
|
+
master_methods = master_methods.collect{|m| m.to_sym}
|
116
|
+
master_methods -= read_only_methods
|
116
117
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
118
|
+
klass = Class.new(self)
|
119
|
+
master_methods.each do |method_name|
|
120
|
+
klass.class_eval <<-EOS, __FILE__, __LINE__ + 1
|
121
|
+
def #{method_name}(*args, &block)
|
122
|
+
use_master_connection do
|
123
|
+
return proxy_connection_method(master_connection, :#{method_name}, :master, *args, &block)
|
124
|
+
end
|
123
125
|
end
|
124
|
-
|
125
|
-
|
126
|
-
end
|
126
|
+
EOS
|
127
|
+
end
|
127
128
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
129
|
+
read_only_methods.each do |method_name|
|
130
|
+
klass.class_eval <<-EOS, __FILE__, __LINE__ + 1
|
131
|
+
def #{method_name}(*args, &block)
|
132
|
+
connection = @use_master ? master_connection : current_read_connection
|
133
|
+
proxy_connection_method(connection, :#{method_name}, :read, *args, &block)
|
134
|
+
end
|
135
|
+
EOS
|
136
|
+
end
|
137
|
+
klass.send :protected, :select
|
137
138
|
|
138
|
-
|
139
|
+
return klass
|
140
|
+
end
|
141
|
+
|
142
|
+
# Set the arel visitor on the connections.
|
143
|
+
def visitor_for(pool)
|
144
|
+
# This is ugly, but then again, so is the code in ActiveRecord for setting the arel
|
145
|
+
# visitor. There is a note in the code indicating the method signatures should be updated.
|
146
|
+
config = pool.spec.config.with_indifferent_access
|
147
|
+
adapter = config[:master][:adapter] || config[:pool_adapter]
|
148
|
+
SeamlessDatabasePool.adapter_class_for(adapter).visitor_for(pool)
|
149
|
+
end
|
139
150
|
end
|
140
151
|
|
141
152
|
def initialize(connection, logger, master_connection, read_connections, pool_weights)
|
@@ -161,7 +172,7 @@ module ActiveRecord
|
|
161
172
|
end
|
162
173
|
|
163
174
|
# Get the pool weight of a connection
|
164
|
-
def pool_weight
|
175
|
+
def pool_weight(connection)
|
165
176
|
return @weighted_read_connections.select{|conn| conn == connection}.size
|
166
177
|
end
|
167
178
|
|
@@ -169,6 +180,14 @@ module ActiveRecord
|
|
169
180
|
false
|
170
181
|
end
|
171
182
|
|
183
|
+
def visitor=(visitor)
|
184
|
+
all_connections.each{|conn| conn.visitor = visitor}
|
185
|
+
end
|
186
|
+
|
187
|
+
def visitor
|
188
|
+
master_connection.visitor
|
189
|
+
end
|
190
|
+
|
172
191
|
def active?
|
173
192
|
active = true
|
174
193
|
do_to_connections {|conn| active &= conn.active?}
|
@@ -237,7 +256,7 @@ module ActiveRecord
|
|
237
256
|
attr_reader :connections, :failed_connection
|
238
257
|
attr_writer :expires
|
239
258
|
|
240
|
-
def initialize
|
259
|
+
def initialize(connections, failed_connection = nil, expires = nil)
|
241
260
|
@connections = connections
|
242
261
|
@failed_connection = failed_connection
|
243
262
|
@expires = expires
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'seamless_database_pool', 'connect_timeout')
|
2
|
-
require File.join(File.dirname(__FILE__), 'seamless_database_pool', 'connection_statistics')
|
3
|
-
require File.join(File.dirname(__FILE__), 'seamless_database_pool', 'controller_filter')
|
4
|
-
require File.join(File.dirname(__FILE__), 'active_record', 'connection_adapters', 'seamless_database_pool_adapter')
|
1
|
+
require File.join(File.dirname(__FILE__), 'seamless_database_pool', 'connect_timeout.rb')
|
2
|
+
require File.join(File.dirname(__FILE__), 'seamless_database_pool', 'connection_statistics.rb')
|
3
|
+
require File.join(File.dirname(__FILE__), 'seamless_database_pool', 'controller_filter.rb')
|
4
|
+
require File.join(File.dirname(__FILE__), 'active_record', 'connection_adapters', 'seamless_database_pool_adapter.rb')
|
5
5
|
$LOAD_PATH << File.dirname(__FILE__) unless $LOAD_PATH.include?(File.dirname(__FILE__))
|
6
6
|
|
7
7
|
# This module allows setting the read pool connection type. Generally you will use one of
|
@@ -15,7 +15,12 @@ $LOAD_PATH << File.dirname(__FILE__) unless $LOAD_PATH.include?(File.dirname(__F
|
|
15
15
|
# read connection type. If none is ever called, the read connection type will be :master.
|
16
16
|
|
17
17
|
module SeamlessDatabasePool
|
18
|
-
|
18
|
+
|
19
|
+
# Adapter name to class name map. This exists because there isn't an obvious way to translate things like
|
20
|
+
# sqlite3 to SQLite3. The adapters that ship with ActiveRecord are defined here. If you use
|
21
|
+
# an adapter that doesn't translate directly to camel case, then add the mapping here in an initializer.
|
22
|
+
ADAPTER_TO_CLASS_NAME_MAP = {"sqlite" => "SQLite", "sqlite3" => "SQLite3", "postgresql" => "PostgreSQL"}
|
23
|
+
|
19
24
|
READ_CONNECTION_METHODS = [:master, :persistent, :random]
|
20
25
|
|
21
26
|
class << self
|
@@ -111,6 +116,16 @@ module SeamlessDatabasePool
|
|
111
116
|
def clear_read_only_connection
|
112
117
|
Thread.current[:read_only_connection] = nil
|
113
118
|
end
|
119
|
+
|
120
|
+
# Get the connection adapter class for an adapter name. The class will be loaded from
|
121
|
+
# ActiveRecord::ConnectionAdapters::NameAdapter where Name is the camelized version of the name.
|
122
|
+
# If the adapter class does not fit this pattern (i.e. sqlite3 => SQLite3Adapter), then add
|
123
|
+
# the mapping to the +ADAPTER_TO_CLASS_NAME_MAP+ Hash.
|
124
|
+
def adapter_class_for(name)
|
125
|
+
name = name.to_s
|
126
|
+
class_name = ADAPTER_TO_CLASS_NAME_MAP[name] || name.camelize
|
127
|
+
"ActiveRecord::ConnectionAdapters::#{class_name}Adapter".constantize
|
128
|
+
end
|
114
129
|
end
|
115
130
|
|
116
131
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'active_record/connection_adapters/read_only_adapter'
|
2
3
|
|
3
4
|
describe "Test connection adapters" do
|
4
5
|
if SeamlessDatabasePool::TestModel.database_configs.empty?
|
@@ -41,32 +42,32 @@ describe "Test connection adapters" do
|
|
41
42
|
it "should quote table names properly" do
|
42
43
|
connection.quote_table_name("foo").should == master_connection.quote_table_name("foo")
|
43
44
|
end
|
44
|
-
|
45
|
+
|
45
46
|
it "should quote column names properly" do
|
46
47
|
connection.quote_column_name("foo").should == master_connection.quote_column_name("foo")
|
47
48
|
end
|
48
|
-
|
49
|
+
|
49
50
|
it "should quote string properly" do
|
50
51
|
connection.quote_string("foo").should == master_connection.quote_string("foo")
|
51
52
|
end
|
52
|
-
|
53
|
+
|
53
54
|
it "should quote booleans properly" do
|
54
55
|
connection.quoted_true.should == master_connection.quoted_true
|
55
56
|
connection.quoted_false.should == master_connection.quoted_false
|
56
57
|
end
|
57
|
-
|
58
|
+
|
58
59
|
it "should quote dates properly" do
|
59
60
|
date = Date.today
|
60
61
|
time = Time.now
|
61
62
|
connection.quoted_date(date).should == master_connection.quoted_date(date)
|
62
63
|
connection.quoted_date(time).should == master_connection.quoted_date(time)
|
63
64
|
end
|
64
|
-
|
65
|
+
|
65
66
|
it "should query for records" do
|
66
67
|
record = model.find_by_name("test")
|
67
68
|
record.name.should == "test"
|
68
69
|
end
|
69
|
-
|
70
|
+
|
70
71
|
it "should work with query caching" do
|
71
72
|
record_id = model.first.id
|
72
73
|
model.cache do
|
@@ -76,62 +77,62 @@ describe "Test connection adapters" do
|
|
76
77
|
model.find(record_id).name.should == "new value"
|
77
78
|
end
|
78
79
|
end
|
79
|
-
|
80
|
+
|
80
81
|
context "read connection" do
|
81
82
|
let(:sample_sql){"SELECT #{connection.quote_column_name('name')} FROM #{connection.quote_table_name(model.table_name)}"}
|
82
|
-
|
83
|
+
|
83
84
|
it "should not include the master connection in the read pool for these tests" do
|
84
85
|
connection.available_read_connections.should_not include(master_connection)
|
85
86
|
connection.current_read_connection.should_not == master_connection
|
86
87
|
end
|
87
|
-
|
88
|
+
|
88
89
|
it "should send select to the read connection" do
|
89
90
|
results = connection.send(:select, sample_sql)
|
90
91
|
results.should == [{"name" => "test"}]
|
91
92
|
results.should == master_connection.send(:select, sample_sql)
|
92
93
|
results.should be_read_only
|
93
94
|
end
|
94
|
-
|
95
|
+
|
95
96
|
it "should send select_all to the read connection" do
|
96
97
|
results = connection.select_all(sample_sql)
|
97
98
|
results.should == [{"name" => "test"}]
|
98
99
|
results.should == master_connection.select_all(sample_sql)
|
99
100
|
results.should be_read_only
|
100
101
|
end
|
101
|
-
|
102
|
+
|
102
103
|
it "should send select_one to the read connection" do
|
103
104
|
results = connection.select_one(sample_sql)
|
104
105
|
results.should == {"name" => "test"}
|
105
106
|
results.should == master_connection.select_one(sample_sql)
|
106
107
|
results.should be_read_only
|
107
108
|
end
|
108
|
-
|
109
|
+
|
109
110
|
it "should send select_values to the read connection" do
|
110
111
|
results = connection.select_values(sample_sql)
|
111
112
|
results.should == ["test"]
|
112
113
|
results.should == master_connection.select_values(sample_sql)
|
113
114
|
results.should be_read_only
|
114
115
|
end
|
115
|
-
|
116
|
+
|
116
117
|
it "should send select_value to the read connection" do
|
117
118
|
results = connection.select_value(sample_sql)
|
118
119
|
results.should == "test"
|
119
120
|
results.should == master_connection.select_value(sample_sql)
|
120
121
|
results.should be_read_only
|
121
122
|
end
|
122
|
-
|
123
|
+
|
123
124
|
it "should send select_rows to the read connection" do
|
124
125
|
results = connection.select_all(sample_sql)
|
125
126
|
results.should == [{"name" => "test"}]
|
126
127
|
results.should == master_connection.select_all(sample_sql)
|
127
128
|
results.should be_read_only
|
128
129
|
end
|
129
|
-
|
130
|
+
|
130
131
|
it "should send execute to the read connection" do
|
131
132
|
results = connection.execute(sample_sql)
|
132
133
|
results.should be_read_only
|
133
134
|
end
|
134
|
-
|
135
|
+
|
135
136
|
it "should send columns to the read connection" do
|
136
137
|
results = connection.columns(model.table_name)
|
137
138
|
columns = results.collect{|c| c.name}.sort.should
|
@@ -139,14 +140,14 @@ describe "Test connection adapters" do
|
|
139
140
|
columns.should == master_connection.columns(model.table_name).collect{|c| c.name}.sort
|
140
141
|
results.should be_read_only
|
141
142
|
end
|
142
|
-
|
143
|
+
|
143
144
|
it "should send tables to the read connection" do
|
144
145
|
results = connection.tables
|
145
146
|
results.should == ["test_models"]
|
146
147
|
results.should == master_connection.tables
|
147
148
|
results.should be_read_only
|
148
149
|
end
|
149
|
-
|
150
|
+
|
150
151
|
it "should reconnect dead connections in the read pool" do
|
151
152
|
read_connection.disconnect!
|
152
153
|
read_connection.should_not be_active
|
@@ -155,12 +156,12 @@ describe "Test connection adapters" do
|
|
155
156
|
read_connection.should be_active
|
156
157
|
end
|
157
158
|
end
|
158
|
-
|
159
|
+
|
159
160
|
context "master connection" do
|
160
161
|
let(:insert_sql){ "INSERT INTO #{connection.quote_table_name(model.table_name)} (#{connection.quote_column_name('name')}) VALUES ('new')" }
|
161
162
|
let(:update_sql){ "UPDATE #{connection.quote_table_name(model.table_name)} SET #{connection.quote_column_name('value')} = 2" }
|
162
163
|
let(:delete_sql){ "DELETE FROM #{connection.quote_table_name(model.table_name)}" }
|
163
|
-
|
164
|
+
|
164
165
|
it "should blow up if a master connection method is sent to the read only connection" do
|
165
166
|
lambda{read_connection.update(update_sql)}.should raise_error(NotImplementedError)
|
166
167
|
lambda{read_connection.update(insert_sql)}.should raise_error(NotImplementedError)
|
@@ -168,29 +169,29 @@ describe "Test connection adapters" do
|
|
168
169
|
lambda{read_connection.transaction{}}.should raise_error(NotImplementedError)
|
169
170
|
lambda{read_connection.create_table(:test)}.should raise_error(NotImplementedError)
|
170
171
|
end
|
171
|
-
|
172
|
+
|
172
173
|
it "should send update to the master connection" do
|
173
174
|
connection.update(update_sql)
|
174
175
|
model.first.value.should == 2
|
175
176
|
end
|
176
|
-
|
177
|
+
|
177
178
|
it "should send insert to the master connection" do
|
178
179
|
connection.update(insert_sql)
|
179
180
|
model.find_by_name("new").should_not == nil
|
180
181
|
end
|
181
|
-
|
182
|
+
|
182
183
|
it "should send delete to the master connection" do
|
183
184
|
connection.update(delete_sql)
|
184
185
|
model.first.should == nil
|
185
186
|
end
|
186
|
-
|
187
|
+
|
187
188
|
it "should send transaction to the master connection" do
|
188
189
|
connection.transaction do
|
189
190
|
connection.update(update_sql)
|
190
191
|
end
|
191
192
|
model.first.value.should == 2
|
192
193
|
end
|
193
|
-
|
194
|
+
|
194
195
|
it "should send schema altering statements to the master connection" do
|
195
196
|
SeamlessDatabasePool.use_master_connection do
|
196
197
|
begin
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
class Base
|
3
|
-
def self.read_only_connection
|
3
|
+
def self.read_only_connection(config)
|
4
4
|
real_adapter = config.delete("real_adapter")
|
5
5
|
connection = send("#{real_adapter}_connection", config.merge("adapter" => real_adapter))
|
6
6
|
ConnectionAdapters::ReadOnlyAdapter.new(connection)
|
@@ -10,7 +10,7 @@ module ActiveRecord
|
|
10
10
|
module ConnectionAdapters
|
11
11
|
class ReadOnlyAdapter < AbstractAdapter
|
12
12
|
%w(select_one select_all select_value select_values select select_rows execute tables columns).each do |read_method|
|
13
|
-
class_eval <<-EOS
|
13
|
+
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
14
14
|
def #{read_method} (*args, &block)
|
15
15
|
raise "Not Connected" unless @connected
|
16
16
|
result = @connection.send(:#{read_method}, *args, &block)
|
@@ -22,7 +22,7 @@ module ActiveRecord
|
|
22
22
|
EOS
|
23
23
|
|
24
24
|
%w(update insert delete reload create_table drop_table add_index remove_index transaction).each do |write_method|
|
25
|
-
class_eval <<-EOS
|
25
|
+
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
26
26
|
def #{write_method} (*args, &block)
|
27
27
|
raise NotImplementedError.new("Master method '#{write_method}' called on read only connection")
|
28
28
|
end
|
@@ -30,11 +30,24 @@ module ActiveRecord
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
def initialize
|
33
|
+
def initialize(connection)
|
34
34
|
@connection = connection
|
35
35
|
@connected = true
|
36
|
+
super
|
36
37
|
end
|
37
|
-
|
38
|
+
|
39
|
+
def test_select
|
40
|
+
@connection.select_all('SELECT "test_models".* FROM "test_models" LIMIT 1')
|
41
|
+
end
|
42
|
+
|
43
|
+
def visitor
|
44
|
+
@connection.visitor
|
45
|
+
end
|
46
|
+
|
47
|
+
def visitor=(v)
|
48
|
+
@connection.visitor = v
|
49
|
+
end
|
50
|
+
|
38
51
|
def reconnect!
|
39
52
|
@connected = true
|
40
53
|
end
|
data/spec/test_model.rb
CHANGED
@@ -5,16 +5,16 @@ module SeamlessDatabasePool
|
|
5
5
|
adapters = ENV['TEST_ADAPTERS'].blank? ? [] : ENV['TEST_ADAPTERS'].split(/\s+/)
|
6
6
|
configs = {}
|
7
7
|
YAML.load_file(File.expand_path("../database.yml", __FILE__)).each do |adapter_name, adapter_config|
|
8
|
-
configs[adapter_name] = adapter_config if adapters.include?(adapter_name)
|
8
|
+
configs[adapter_name] = adapter_config if adapters.include?(adapter_name.downcase)
|
9
9
|
end
|
10
10
|
configs
|
11
11
|
end
|
12
12
|
|
13
|
-
def use_database_connection
|
13
|
+
def use_database_connection(db_name)
|
14
14
|
establish_connection(database_configs[db_name.to_s])
|
15
15
|
end
|
16
16
|
|
17
|
-
def db_model
|
17
|
+
def db_model(db_name)
|
18
18
|
model_class_name = db_name.classify
|
19
19
|
unless const_defined?(model_class_name)
|
20
20
|
klass = Class.new(self)
|
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: seamless_database_pool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 5
|
5
4
|
prerelease:
|
6
|
-
|
7
|
-
- 1
|
8
|
-
- 0
|
9
|
-
- 9
|
10
|
-
version: 1.0.9
|
5
|
+
version: 1.0.10
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Brian Durand
|
@@ -15,7 +10,7 @@ autorequire:
|
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
12
|
|
18
|
-
date: 2011-
|
13
|
+
date: 2011-10-06 00:00:00 -05:00
|
19
14
|
default_executable:
|
20
15
|
dependencies:
|
21
16
|
- !ruby/object:Gem::Dependency
|
@@ -26,11 +21,6 @@ dependencies:
|
|
26
21
|
requirements:
|
27
22
|
- - ">="
|
28
23
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 3
|
30
|
-
segments:
|
31
|
-
- 2
|
32
|
-
- 2
|
33
|
-
- 2
|
34
24
|
version: 2.2.2
|
35
25
|
type: :runtime
|
36
26
|
version_requirements: *id001
|
@@ -42,10 +32,6 @@ dependencies:
|
|
42
32
|
requirements:
|
43
33
|
- - ">="
|
44
34
|
- !ruby/object:Gem::Version
|
45
|
-
hash: 3
|
46
|
-
segments:
|
47
|
-
- 2
|
48
|
-
- 0
|
49
35
|
version: "2.0"
|
50
36
|
type: :development
|
51
37
|
version_requirements: *id002
|
@@ -57,12 +43,42 @@ dependencies:
|
|
57
43
|
requirements:
|
58
44
|
- - ">="
|
59
45
|
- !ruby/object:Gem::Version
|
60
|
-
hash: 3
|
61
|
-
segments:
|
62
|
-
- 0
|
63
46
|
version: "0"
|
64
47
|
type: :development
|
65
48
|
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: sqlite3
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: mysql
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id005
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: pg
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "0"
|
80
|
+
type: :development
|
81
|
+
version_requirements: *id006
|
66
82
|
description:
|
67
83
|
email: brian@embellishedvisions.com
|
68
84
|
executables: []
|
@@ -105,25 +121,26 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
105
121
|
requirements:
|
106
122
|
- - ">="
|
107
123
|
- !ruby/object:Gem::Version
|
108
|
-
hash: 3
|
109
|
-
segments:
|
110
|
-
- 0
|
111
124
|
version: "0"
|
112
125
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
126
|
none: false
|
114
127
|
requirements:
|
115
128
|
- - ">="
|
116
129
|
- !ruby/object:Gem::Version
|
117
|
-
hash: 3
|
118
|
-
segments:
|
119
|
-
- 0
|
120
130
|
version: "0"
|
121
131
|
requirements: []
|
122
132
|
|
123
133
|
rubyforge_project:
|
124
|
-
rubygems_version: 1.
|
134
|
+
rubygems_version: 1.6.2
|
125
135
|
signing_key:
|
126
136
|
specification_version: 3
|
127
137
|
summary: Add support for master/slave database clusters in ActiveRecord to improve performance.
|
128
|
-
test_files:
|
129
|
-
|
138
|
+
test_files:
|
139
|
+
- spec/connection_adapters_spec.rb
|
140
|
+
- spec/connection_statistics_spec.rb
|
141
|
+
- spec/controller_filter_spec.rb
|
142
|
+
- spec/seamless_database_pool_adapter_spec.rb
|
143
|
+
- spec/seamless_database_pool_spec.rb
|
144
|
+
- spec/spec_helper.rb
|
145
|
+
- spec/test_adapter/active_record/connection_adapters/read_only_adapter.rb
|
146
|
+
- spec/test_model.rb
|