seamless_database_pool 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,212 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
2
+
3
+ describe "Test connection adapters" do
4
+ if SeamlessDatabasePool::TestModel.database_configs.empty?
5
+ puts "No adapters specified for testing. Specify the adapters with TEST_ADAPTERS variable"
6
+ else
7
+ SeamlessDatabasePool::TestModel.database_configs.keys.each do |adapter|
8
+ context adapter do
9
+ let(:model){ SeamlessDatabasePool::TestModel.db_model(adapter)}
10
+ let(:connection){ model.connection }
11
+ let(:read_connection){ connection.available_read_connections.first }
12
+ let(:master_connection){ connection.master_connection }
13
+
14
+ before(:all) do
15
+ model.use_database_connection(adapter)
16
+ model.create_tables
17
+ end
18
+
19
+ after(:all) do
20
+ model.drop_tables
21
+ model.cleanup_database!
22
+ end
23
+
24
+ before(:each) do
25
+ model.create!(:name => 'test', :value => 1)
26
+ SeamlessDatabasePool.use_persistent_read_connection
27
+ end
28
+
29
+ after(:each) do
30
+ model.delete_all
31
+ SeamlessDatabasePool.use_master_connection
32
+ end
33
+
34
+ it "should force the master connection on reload" do
35
+ record = model.first
36
+ SeamlessDatabasePool.should_not_receive(:current_read_connection)
37
+ record.reload
38
+ end
39
+
40
+ it "should quote table names properly" do
41
+ connection.quote_table_name("foo").should == master_connection.quote_table_name("foo")
42
+ end
43
+
44
+ it "should quote column names properly" do
45
+ connection.quote_column_name("foo").should == master_connection.quote_column_name("foo")
46
+ end
47
+
48
+ it "should quote string properly" do
49
+ connection.quote_string("foo").should == master_connection.quote_string("foo")
50
+ end
51
+
52
+ it "should quote booleans properly" do
53
+ connection.quoted_true.should == master_connection.quoted_true
54
+ connection.quoted_false.should == master_connection.quoted_false
55
+ end
56
+
57
+ it "should quote dates properly" do
58
+ date = Date.today
59
+ time = Time.now
60
+ connection.quoted_date(date).should == master_connection.quoted_date(date)
61
+ connection.quoted_date(time).should == master_connection.quoted_date(time)
62
+ end
63
+
64
+ it "should query for records" do
65
+ record = model.find_by_name("test")
66
+ record.name.should == "test"
67
+ end
68
+
69
+ it "should work with query caching" do
70
+ record_id = model.first.id
71
+ model.cache do
72
+ found = model.find(record_id)
73
+ found.name = "new value"
74
+ found.save!
75
+ model.find(record_id).name.should == "new value"
76
+ end
77
+ end
78
+
79
+ context "read connection" do
80
+
81
+ let(:sample_sql){"SELECT #{connection.quote_column_name('name')} FROM #{connection.quote_table_name(model.table_name)}"}
82
+
83
+ it "should not include the master connection in the read pool for these tests" do
84
+ connection.available_read_connections.should_not include(master_connection)
85
+ connection.current_read_connection.should_not == master_connection
86
+ end
87
+
88
+ it "should send select to the read connection" do
89
+ results = connection.send(:select, sample_sql)
90
+ results.should == [{"name" => "test"}]
91
+ results.should == master_connection.send(:select, sample_sql)
92
+ results.should be_read_only
93
+ end
94
+
95
+ it "should send select_all to the read connection" do
96
+ results = connection.select_all(sample_sql)
97
+ results.should == [{"name" => "test"}]
98
+ results.should == master_connection.select_all(sample_sql)
99
+ results.should be_read_only
100
+ end
101
+
102
+ it "should send select_one to the read connection" do
103
+ results = connection.select_one(sample_sql)
104
+ results.should == {"name" => "test"}
105
+ results.should == master_connection.select_one(sample_sql)
106
+ results.should be_read_only
107
+ end
108
+
109
+ it "should send select_values to the read connection" do
110
+ results = connection.select_values(sample_sql)
111
+ results.should == ["test"]
112
+ results.should == master_connection.select_values(sample_sql)
113
+ results.should be_read_only
114
+ end
115
+
116
+ it "should send select_value to the read connection" do
117
+ results = connection.select_value(sample_sql)
118
+ results.should == "test"
119
+ results.should == master_connection.select_value(sample_sql)
120
+ results.should be_read_only
121
+ end
122
+
123
+ it "should send select_rows to the read connection" do
124
+ results = connection.select_all(sample_sql)
125
+ results.should == [{"name" => "test"}]
126
+ results.should == master_connection.select_all(sample_sql)
127
+ results.should be_read_only
128
+ end
129
+
130
+ it "should send execute to the read connection" do
131
+ results = connection.execute(sample_sql)
132
+ results.should be_read_only
133
+ end
134
+
135
+ it "should send columns to the read connection" do
136
+ results = connection.columns(model.table_name)
137
+ columns = results.collect{|c| c.name}.sort.should
138
+ columns.should == ["id", "name", "value"]
139
+ columns.should == master_connection.columns(model.table_name).collect{|c| c.name}.sort
140
+ results.should be_read_only
141
+ end
142
+
143
+ it "should send tables to the read connection" do
144
+ results = connection.tables
145
+ results.should == ["test_models"]
146
+ results.should == master_connection.tables
147
+ results.should be_read_only
148
+ end
149
+
150
+ it "should reconnect dead connections in the read pool" do
151
+ read_connection.disconnect!
152
+ read_connection.should_not be_active
153
+ results = connection.select_all(sample_sql)
154
+ results.should be_read_only
155
+ read_connection.should be_active
156
+ end
157
+ end
158
+
159
+ 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')" }
162
+ let(:update_sql){ "UPDATE #{connection.quote_table_name(model.table_name)} SET #{connection.quote_column_name('value')} = 2" }
163
+ let(:delete_sql){ "DELETE FROM #{connection.quote_table_name(model.table_name)}" }
164
+
165
+ it "should blow up if a master connection method is sent to the read only connection" do
166
+ lambda{read_connection.update(update_sql)}.should raise_error(NotImplementedError)
167
+ lambda{read_connection.update(insert_sql)}.should raise_error(NotImplementedError)
168
+ lambda{read_connection.update(delete_sql)}.should raise_error(NotImplementedError)
169
+ lambda{read_connection.transaction{}}.should raise_error(NotImplementedError)
170
+ lambda{read_connection.create_table(:test)}.should raise_error(NotImplementedError)
171
+ end
172
+
173
+ it "should send update to the master connection" do
174
+ connection.update(update_sql)
175
+ model.first.value.should == 2
176
+ end
177
+
178
+ it "should send insert to the master connection" do
179
+ connection.update(insert_sql)
180
+ model.find_by_name("new").should_not == nil
181
+ end
182
+
183
+ it "should send delete to the master connection" do
184
+ connection.update(delete_sql)
185
+ model.first.should == nil
186
+ end
187
+
188
+ it "should send transaction to the master connection" do
189
+ connection.transaction do
190
+ connection.update(update_sql)
191
+ end
192
+ model.first.value.should == 2
193
+ end
194
+
195
+ it "should send schema altering statements to the master connection" do
196
+ SeamlessDatabasePool.use_master_connection do
197
+ begin
198
+ connection.create_table(:foo) do |t|
199
+ t.string :name
200
+ end
201
+ connection.add_index(:foo, :name)
202
+ ensure
203
+ connection.remove_index(:foo, :name)
204
+ connection.drop_table(:foo)
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end
data/spec/database.yml ADDED
@@ -0,0 +1,35 @@
1
+ # This file contains the databases that the test suite will be run against if you run rake:test:adapters or set the
2
+ # environment variable ADAPTER (use commas to test multiple adapters). If you want, you can add your own adapter below
3
+ # and it will be added to the test suite.
4
+
5
+ sqlite3:
6
+ adapter: seamless_database_pool
7
+ database: test.sqlite3
8
+ master:
9
+ adapter: sqlite3
10
+ pool_weight: 0
11
+ read_pool:
12
+ - adapter: read_only
13
+ real_adapter: sqlite3
14
+
15
+ postgresql:
16
+ adapter: seamless_database_pool
17
+ database: seamless_database_pool_test
18
+ username: postgres
19
+ password: postgres
20
+ master:
21
+ adapter: postgresql
22
+ pool_weight: 0
23
+ read_pool:
24
+ - adapter: read_only
25
+ real_adapter: postgresql
26
+
27
+ mysql:
28
+ adapter: seamless_database_pool
29
+ database: seamless_database_pool_test
30
+ master:
31
+ adapter: mysql
32
+ pool_weight: 0
33
+ read_pool:
34
+ - adapter: read_only
35
+ real_adapter: mysql