seamless_database_pool 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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