apartment 0.22.1 → 0.23.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -2
- data/.rspec +2 -1
- data/.travis.yml +3 -1
- data/Appraisals +7 -0
- data/Gemfile +0 -21
- data/HISTORY.md +6 -0
- data/README.md +13 -71
- data/Rakefile +4 -2
- data/TODO.md +0 -5
- data/apartment.gemspec +19 -0
- data/gemfiles/rails3.2.gemfile +7 -0
- data/gemfiles/rails4.0.gemfile +7 -0
- data/lib/apartment.rb +2 -28
- data/lib/apartment/adapters/abstract_adapter.rb +0 -2
- data/lib/apartment/adapters/abstract_jdbc_adapter.rb +2 -0
- data/lib/apartment/adapters/jdbc_mysql_adapter.rb +2 -0
- data/lib/apartment/adapters/jdbc_postgresql_adapter.rb +1 -1
- data/lib/apartment/adapters/mysql2_adapter.rb +2 -3
- data/lib/apartment/adapters/postgis_adapter.rb +0 -1
- data/lib/apartment/adapters/postgresql_adapter.rb +2 -3
- data/lib/apartment/adapters/sqlite3_adapter.rb +2 -0
- data/lib/apartment/database.rb +0 -4
- data/lib/apartment/elevators/domain.rb +2 -0
- data/lib/apartment/elevators/first_subdomain.rb +2 -0
- data/lib/apartment/elevators/generic.rb +3 -0
- data/lib/apartment/elevators/host_hash.rb +2 -0
- data/lib/apartment/elevators/subdomain.rb +19 -2
- data/lib/apartment/migrator.rb +2 -1
- data/lib/apartment/railtie.rb +2 -2
- data/lib/apartment/reloader.rb +0 -3
- data/lib/apartment/version.rb +2 -2
- data/lib/tasks/apartment.rake +2 -0
- data/spec/adapters/jdbc_mysql_adapter_spec.rb +1 -3
- data/spec/adapters/jdbc_postgresql_adapter_spec.rb +1 -3
- data/spec/adapters/mysql2_adapter_spec.rb +1 -2
- data/spec/adapters/postgresql_adapter_spec.rb +1 -2
- data/spec/adapters/sqlite3_adapter_spec.rb +1 -2
- data/spec/database_spec.rb +32 -50
- data/spec/dummy/app/models/user.rb +0 -2
- data/spec/dummy/config/application.rb +2 -0
- data/spec/dummy/config/environments/development.rb +2 -0
- data/spec/dummy/config/environments/production.rb +2 -0
- data/spec/dummy/config/environments/test.rb +1 -2
- data/spec/dummy/config/initializers/apartment.rb +1 -1
- data/spec/dummy/db/seeds.rb +1 -4
- data/spec/examples/elevator_examples.rb +4 -4
- data/spec/integration/apartment_rake_integration_spec.rb +15 -19
- data/spec/integration/middleware/domain_elevator_spec.rb +4 -3
- data/spec/integration/middleware/generic_elevator_spec.rb +4 -3
- data/spec/integration/middleware/subdomain_elevator_spec.rb +29 -3
- data/spec/integration/query_caching_spec.rb +8 -4
- data/spec/schemas/v1.rb +16 -0
- data/spec/schemas/v2.rb +43 -0
- data/spec/schemas/v3.rb +49 -0
- data/spec/spec_helper.rb +5 -11
- data/spec/support/apartment_helpers.rb +4 -2
- data/spec/support/contexts.rb +15 -19
- data/spec/support/requirements.rb +1 -17
- data/spec/support/setup.rb +47 -0
- data/spec/tasks/apartment_rake_spec.rb +6 -3
- data/spec/unit/config_spec.rb +3 -3
- data/spec/unit/middleware/domain_elevator_spec.rb +1 -2
- data/spec/{integration → unit}/middleware/first_subdomain_elevator_spec.rb +1 -0
- data/spec/unit/middleware/host_hash_elevator_spec.rb +1 -2
- data/spec/unit/middleware/subdomain_elevator_spec.rb +1 -2
- data/spec/unit/migrator_spec.rb +5 -4
- data/spec/unit/reloader_spec.rb +6 -4
- metadata +130 -14
- data/lib/apartment/delayed_job/enqueue.rb +0 -26
- data/lib/apartment/delayed_job/hooks.rb +0 -26
- data/lib/apartment/delayed_job/psych_ext.rb +0 -61
- data/lib/apartment/delayed_job/requirements.rb +0 -23
- data/lib/apartment/delayed_job/syck_ext.rb +0 -29
- data/spec/dummy/lib/fake_dj_class.rb +0 -6
- data/spec/integration/delayed_job_integration_spec.rb +0 -99
@@ -1,12 +1,29 @@
|
|
1
|
+
require 'apartment/elevators/generic'
|
2
|
+
|
1
3
|
module Apartment
|
2
4
|
module Elevators
|
3
5
|
# Provides a rack based db switching solution based on subdomains
|
4
6
|
# Assumes that database name should match subdomain
|
5
7
|
#
|
6
8
|
class Subdomain < Generic
|
9
|
+
def self.excluded_subdomains
|
10
|
+
@@excluded_subdomains ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.excluded_subdomains=(arg)
|
14
|
+
@@excluded_subdomains = arg
|
15
|
+
end
|
7
16
|
|
8
17
|
def parse_database_name(request)
|
9
|
-
|
18
|
+
request_subdomain = subdomain(request.host)
|
19
|
+
|
20
|
+
# If the domain acquired is set to be exlcluded, set the database to whatever is currently
|
21
|
+
# next in line in the schema search path.
|
22
|
+
database = if self.class.excluded_subdomains.include?(request_subdomain)
|
23
|
+
nil
|
24
|
+
else
|
25
|
+
request_subdomain
|
26
|
+
end
|
10
27
|
|
11
28
|
database.present? && database || nil
|
12
29
|
end
|
@@ -32,4 +49,4 @@ module Apartment
|
|
32
49
|
end
|
33
50
|
end
|
34
51
|
end
|
35
|
-
end
|
52
|
+
end
|
data/lib/apartment/migrator.rb
CHANGED
data/lib/apartment/railtie.rb
CHANGED
data/lib/apartment/reloader.rb
CHANGED
data/lib/apartment/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Apartment
|
2
|
-
VERSION = "0.
|
3
|
-
end
|
2
|
+
VERSION = "0.23.0"
|
3
|
+
end
|
data/lib/tasks/apartment.rake
CHANGED
@@ -3,10 +3,8 @@ if defined?(JRUBY_VERSION)
|
|
3
3
|
require 'spec_helper'
|
4
4
|
require 'lib/apartment/adapters/jdbc_mysql_adapter'
|
5
5
|
|
6
|
-
describe Apartment::Adapters::JDBCMysqlAdapter do
|
6
|
+
describe Apartment::Adapters::JDBCMysqlAdapter, database: :mysql do
|
7
7
|
|
8
|
-
|
9
|
-
let(:config) { Apartment::Test.config['connections']['mysql'] }
|
10
8
|
subject { Apartment::Database.jdbc_mysql_adapter config.symbolize_keys }
|
11
9
|
|
12
10
|
def database_names
|
@@ -3,10 +3,8 @@ if defined?(JRUBY_VERSION)
|
|
3
3
|
require 'spec_helper'
|
4
4
|
require 'lib/apartment/adapters/jdbc_postgresql_adapter'
|
5
5
|
|
6
|
-
describe Apartment::Adapters::JDBCPostgresqlAdapter do
|
6
|
+
describe Apartment::Adapters::JDBCPostgresqlAdapter, database: :postgresql do
|
7
7
|
|
8
|
-
|
9
|
-
let(:config) { Apartment::Test.config['connections']['postgresql'] }
|
10
8
|
subject { Apartment::Database.jdbc_postgresql_adapter config.symbolize_keys }
|
11
9
|
|
12
10
|
context "using schemas" do
|
@@ -1,10 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'apartment/adapters/mysql2_adapter'
|
3
3
|
|
4
|
-
describe Apartment::Adapters::Mysql2Adapter do
|
4
|
+
describe Apartment::Adapters::Mysql2Adapter, database: :mysql do
|
5
5
|
unless defined?(JRUBY_VERSION)
|
6
6
|
|
7
|
-
let(:config){ Apartment::Test.config['connections']['mysql'].symbolize_keys }
|
8
7
|
subject(:adapter){ Apartment::Database.mysql2_adapter config }
|
9
8
|
|
10
9
|
def database_names
|
@@ -1,10 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'apartment/adapters/postgresql_adapter'
|
3
3
|
|
4
|
-
describe Apartment::Adapters::PostgresqlAdapter do
|
4
|
+
describe Apartment::Adapters::PostgresqlAdapter, database: :postgresql do
|
5
5
|
unless defined?(JRUBY_VERSION)
|
6
6
|
|
7
|
-
let(:config){ Apartment::Test.config['connections']['postgresql'].symbolize_keys }
|
8
7
|
subject{ Apartment::Database.postgresql_adapter config }
|
9
8
|
|
10
9
|
context "using schemas" do
|
@@ -1,10 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'apartment/adapters/sqlite3_adapter'
|
3
3
|
|
4
|
-
describe Apartment::Adapters::Sqlite3Adapter do
|
4
|
+
describe Apartment::Adapters::Sqlite3Adapter, database: :sqlite do
|
5
5
|
unless defined?(JRUBY_VERSION)
|
6
6
|
|
7
|
-
let(:config){ Apartment::Test.config['connections']['sqlite'].symbolize_keys }
|
8
7
|
subject{ Apartment::Database.sqlite3_adapter config }
|
9
8
|
|
10
9
|
context "using connections" do
|
data/spec/database_spec.rb
CHANGED
@@ -1,14 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Apartment::Database do
|
4
|
-
context "using mysql" do
|
5
|
-
# See apartment.yml file in dummy app config
|
6
|
-
|
7
|
-
let(:config){ Apartment::Test.config['connections']['mysql'].symbolize_keys }
|
4
|
+
context "using mysql", database: :mysql do
|
8
5
|
|
9
6
|
before do
|
10
|
-
ActiveRecord::Base.establish_connection config
|
11
|
-
Apartment::Test.load_schema # load the Rails schema in the public db schema
|
12
7
|
subject.stub(:config).and_return config # Use mysql database config for this test
|
13
8
|
end
|
14
9
|
|
@@ -26,25 +21,22 @@ describe Apartment::Database do
|
|
26
21
|
# TODO this doesn't belong here, but there aren't integration tests currently for mysql
|
27
22
|
# where to put???
|
28
23
|
describe "#exception recovery", :type => :request do
|
29
|
-
let(:database1){ Apartment::Test.next_db }
|
30
|
-
|
31
24
|
before do
|
32
25
|
subject.reload!
|
33
|
-
subject.create
|
26
|
+
subject.create db1
|
34
27
|
end
|
35
|
-
after{ subject.drop
|
36
|
-
|
37
|
-
it "should recover from incorrect database" do
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
45
|
-
|
28
|
+
after{ subject.drop db1 }
|
29
|
+
|
30
|
+
# it "should recover from incorrect database" do
|
31
|
+
# session = Capybara::Session.new(:rack_test, Capybara.app)
|
32
|
+
# session.visit("http://#{db1}.com")
|
33
|
+
# expect {
|
34
|
+
# session.visit("http://this-database-should-not-exist.com")
|
35
|
+
# }.to raise_error
|
36
|
+
# session.visit("http://#{db1}.com")
|
37
|
+
# end
|
46
38
|
end
|
47
|
-
|
39
|
+
|
48
40
|
context "with prefix and schemas" do
|
49
41
|
describe "#create" do
|
50
42
|
before do
|
@@ -52,11 +44,12 @@ describe Apartment::Database do
|
|
52
44
|
config.prepend_environment = true
|
53
45
|
config.use_schemas = true
|
54
46
|
end
|
47
|
+
|
55
48
|
subject.reload!(config) # switch to Mysql2SchemaAdapter
|
56
49
|
end
|
57
|
-
|
50
|
+
|
58
51
|
after { subject.drop "db_with_prefix" rescue nil }
|
59
|
-
|
52
|
+
|
60
53
|
it "should create a new database" do
|
61
54
|
subject.create "db_with_prefix"
|
62
55
|
end
|
@@ -64,18 +57,9 @@ describe Apartment::Database do
|
|
64
57
|
end
|
65
58
|
end
|
66
59
|
|
67
|
-
context "using postgresql" do
|
68
|
-
|
69
|
-
# See apartment.yml file in dummy app config
|
70
|
-
|
71
|
-
let(:config){ Apartment::Test.config['connections']['postgresql'].symbolize_keys }
|
72
|
-
let(:database){ Apartment::Test.next_db }
|
73
|
-
let(:database2){ Apartment::Test.next_db }
|
74
|
-
|
60
|
+
context "using postgresql", database: :postgresql do
|
75
61
|
before do
|
76
62
|
Apartment.use_schemas = true
|
77
|
-
ActiveRecord::Base.establish_connection config
|
78
|
-
Apartment::Test.load_schema # load the Rails schema in the public db schema
|
79
63
|
subject.stub(:config).and_return config # Use postgresql database config for this test
|
80
64
|
end
|
81
65
|
|
@@ -90,7 +74,7 @@ describe Apartment::Database do
|
|
90
74
|
end
|
91
75
|
|
92
76
|
it "should raise exception with invalid adapter specified" do
|
93
|
-
subject.stub(:config).and_return config.merge(:adapter => '
|
77
|
+
subject.stub(:config).and_return config.merge(:adapter => 'unknown')
|
94
78
|
|
95
79
|
expect {
|
96
80
|
Apartment::Database.adapter
|
@@ -98,13 +82,14 @@ describe Apartment::Database do
|
|
98
82
|
end
|
99
83
|
|
100
84
|
context "threadsafety" do
|
101
|
-
before { subject.create
|
85
|
+
before { subject.create db1 }
|
86
|
+
after { subject.drop db1 }
|
102
87
|
|
103
88
|
it 'has a threadsafe adapter' do
|
104
|
-
subject.switch(
|
89
|
+
subject.switch(db1)
|
105
90
|
thread = Thread.new { subject.current_database.should == Apartment.default_schema }
|
106
91
|
thread.join
|
107
|
-
subject.current_database.should ==
|
92
|
+
subject.current_database.should == db1
|
108
93
|
end
|
109
94
|
end
|
110
95
|
end
|
@@ -117,14 +102,14 @@ describe Apartment::Database do
|
|
117
102
|
config.use_schemas = true
|
118
103
|
config.seed_after_create = true
|
119
104
|
end
|
120
|
-
subject.create
|
105
|
+
subject.create db1
|
121
106
|
end
|
122
107
|
|
123
|
-
after{ subject.drop
|
108
|
+
after{ subject.drop db1 }
|
124
109
|
|
125
110
|
describe "#create" do
|
126
111
|
it "should seed data" do
|
127
|
-
subject.switch
|
112
|
+
subject.switch db1
|
128
113
|
User.count.should be > 0
|
129
114
|
end
|
130
115
|
end
|
@@ -135,20 +120,20 @@ describe Apartment::Database do
|
|
135
120
|
|
136
121
|
context "creating models" do
|
137
122
|
|
138
|
-
before{ subject.create
|
139
|
-
after{ subject.drop
|
123
|
+
before{ subject.create db2 }
|
124
|
+
after{ subject.drop db2 }
|
140
125
|
|
141
126
|
it "should create a model instance in the current schema" do
|
142
|
-
subject.switch
|
127
|
+
subject.switch db2
|
143
128
|
db2_count = User.count + x.times{ User.create }
|
144
129
|
|
145
|
-
subject.switch
|
130
|
+
subject.switch db1
|
146
131
|
db_count = User.count + x.times{ User.create }
|
147
132
|
|
148
|
-
subject.switch
|
133
|
+
subject.switch db2
|
149
134
|
User.count.should == db2_count
|
150
135
|
|
151
|
-
subject.switch
|
136
|
+
subject.switch db1
|
152
137
|
User.count.should == db_count
|
153
138
|
end
|
154
139
|
end
|
@@ -166,17 +151,14 @@ describe Apartment::Database do
|
|
166
151
|
subject.reset # ensure we're on public schema
|
167
152
|
count = Company.count + x.times{ Company.create }
|
168
153
|
|
169
|
-
subject.switch
|
154
|
+
subject.switch db1
|
170
155
|
x.times{ Company.create }
|
171
156
|
Company.count.should == count + x
|
172
157
|
subject.reset
|
173
158
|
Company.count.should == count + x
|
174
159
|
end
|
175
160
|
end
|
176
|
-
|
177
161
|
end
|
178
|
-
|
179
162
|
end
|
180
|
-
|
181
163
|
end
|
182
164
|
end
|
@@ -14,6 +14,8 @@ module Dummy
|
|
14
14
|
# Settings in config/environments/* take precedence over those specified here.
|
15
15
|
# Application configuration should go into files in config/initializers
|
16
16
|
# -- all .rb files in that directory are automatically loaded.
|
17
|
+
require 'apartment/elevators/subdomain'
|
18
|
+
require 'apartment/elevators/domain'
|
17
19
|
|
18
20
|
config.middleware.use 'Apartment::Elevators::Subdomain'
|
19
21
|
config.middleware.use 'Apartment::Elevators::Domain'
|
@@ -6,6 +6,8 @@ Dummy::Application.configure do
|
|
6
6
|
# since you don't have to restart the webserver when you make code changes.
|
7
7
|
config.cache_classes = false
|
8
8
|
|
9
|
+
config.eager_load = false
|
10
|
+
|
9
11
|
# Log error messages when you accidentally call methods on nil.
|
10
12
|
config.whiny_nils = true
|
11
13
|
|
@@ -5,6 +5,8 @@ Dummy::Application.configure do
|
|
5
5
|
# Code is not reloaded between requests
|
6
6
|
config.cache_classes = true
|
7
7
|
|
8
|
+
config.eager_load = true
|
9
|
+
|
8
10
|
# Full error reports are disabled and caching is turned on
|
9
11
|
config.consider_all_requests_local = false
|
10
12
|
config.action_controller.perform_caching = true
|
@@ -7,8 +7,7 @@ Dummy::Application.configure do
|
|
7
7
|
# and recreated between test runs. Don't rely on the data there!
|
8
8
|
config.cache_classes = true
|
9
9
|
|
10
|
-
|
11
|
-
config.whiny_nils = true
|
10
|
+
config.eager_load = false
|
12
11
|
|
13
12
|
# Show full error reports and disable caching
|
14
13
|
config.consider_all_requests_local = true
|
data/spec/dummy/db/seeds.rb
CHANGED
@@ -4,17 +4,17 @@ shared_examples_for "an apartment elevator" do
|
|
4
4
|
|
5
5
|
context "single request" do
|
6
6
|
it "should switch the db" do
|
7
|
-
ActiveRecord::Base.connection.schema_search_path.should_not == %{"#{
|
7
|
+
ActiveRecord::Base.connection.schema_search_path.should_not == %{"#{db1}"}
|
8
8
|
|
9
9
|
visit(domain1)
|
10
|
-
ActiveRecord::Base.connection.schema_search_path.should == %{"#{
|
10
|
+
ActiveRecord::Base.connection.schema_search_path.should == %{"#{db1}"}
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
14
|
context "simultaneous requests" do
|
15
15
|
|
16
|
-
let!(:c1_user_count) { api.process(
|
17
|
-
let!(:c2_user_count) { api.process(
|
16
|
+
let!(:c1_user_count) { api.process(db1){ (2 + rand(2)).times{ User.create } } }
|
17
|
+
let!(:c2_user_count) { api.process(db2){ (c1_user_count + 2).times{ User.create } } }
|
18
18
|
|
19
19
|
it "should fetch the correct user count for each session based on the elevator processor" do
|
20
20
|
visit(domain1)
|