dr-apartment 0.14.1
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.
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +22 -0
- data/HISTORY.md +133 -0
- data/README.md +152 -0
- data/Rakefile +79 -0
- data/apartment.gemspec +32 -0
- data/lib/apartment.rb +69 -0
- data/lib/apartment/adapters/abstract_adapter.rb +176 -0
- data/lib/apartment/adapters/jdbcpostgresql_adapter.rb +115 -0
- data/lib/apartment/adapters/mysql_adapter.rb +18 -0
- data/lib/apartment/adapters/postgresql_adapter.rb +114 -0
- data/lib/apartment/console.rb +12 -0
- data/lib/apartment/database.rb +57 -0
- data/lib/apartment/delayed_job/active_record.rb +20 -0
- data/lib/apartment/delayed_job/enqueue.rb +20 -0
- data/lib/apartment/delayed_job/hooks.rb +25 -0
- data/lib/apartment/delayed_job/requirements.rb +23 -0
- data/lib/apartment/elevators/subdomain.rb +27 -0
- data/lib/apartment/migrator.rb +23 -0
- data/lib/apartment/railtie.rb +54 -0
- data/lib/apartment/reloader.rb +24 -0
- data/lib/apartment/version.rb +3 -0
- data/lib/tasks/apartment.rake +70 -0
- data/spec/adapters/mysql_adapter_spec.rb +36 -0
- data/spec/adapters/postgresql_adapter_spec.rb +137 -0
- data/spec/apartment_spec.rb +11 -0
- data/spec/config/database.yml +13 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +6 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/company.rb +3 -0
- data/spec/dummy/app/models/user.rb +3 -0
- data/spec/dummy/app/views/application/index.html.erb +1 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +47 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +16 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +26 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +35 -0
- data/spec/dummy/config/initializers/apartment.rb +4 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/db/migrate/20110613152810_create_dummy_models.rb +37 -0
- data/spec/dummy/db/migrate/20111202022214_create_table_books.rb +13 -0
- data/spec/dummy/db/schema.rb +48 -0
- data/spec/dummy/db/seeds.rb +8 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/lib/fake_dj_class.rb +6 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/integration/apartment_rake_integration_spec.rb +74 -0
- data/spec/integration/database_integration_spec.rb +200 -0
- data/spec/integration/delayed_job_integration_spec.rb +100 -0
- data/spec/integration/middleware/subdomain_elevator_spec.rb +63 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/support/apartment_helpers.rb +32 -0
- data/spec/support/capybara_sessions.rb +15 -0
- data/spec/support/config.rb +11 -0
- data/spec/tasks/apartment_rake_spec.rb +118 -0
- data/spec/unit/config_spec.rb +78 -0
- data/spec/unit/middleware/subdomain_elevator_spec.rb +20 -0
- data/spec/unit/migrator_spec.rb +87 -0
- data/spec/unit/reloader_spec.rb +22 -0
- metadata +144 -0
Binary file
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/404.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
23
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
24
|
+
</div>
|
25
|
+
</body>
|
26
|
+
</html>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/422.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>The change you wanted was rejected.</h1>
|
23
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
24
|
+
</div>
|
25
|
+
</body>
|
26
|
+
</html>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/500.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>We're sorry, but something went wrong.</h1>
|
23
|
+
<p>We've been notified about this issue and we'll take a look at it shortly.</p>
|
24
|
+
</div>
|
25
|
+
</body>
|
26
|
+
</html>
|
File without changes
|
File without changes
|
@@ -0,0 +1,6 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
3
|
+
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
6
|
+
require 'rails/commands'
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
describe "apartment rake tasks" do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@rake = Rake::Application.new
|
8
|
+
Rake.application = @rake
|
9
|
+
Dummy::Application.load_tasks
|
10
|
+
|
11
|
+
# somehow this misc.rake file gets lost in the shuffle
|
12
|
+
# it defines a `rails_env` task that our db:migrate depends on
|
13
|
+
# No idea why, but during the tests, we somehow lose this tasks, so we get an error when testing migrations
|
14
|
+
# This is STUPID!
|
15
|
+
load "rails/tasks/misc.rake"
|
16
|
+
end
|
17
|
+
|
18
|
+
after do
|
19
|
+
Rake.application = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
before do
|
23
|
+
Apartment.configure do |config|
|
24
|
+
config.excluded_models = ["Company"]
|
25
|
+
config.database_names = lambda{ Company.scoped.collect(&:database) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with x number of databases" do
|
30
|
+
|
31
|
+
let(:x){ 1 + rand(5) } # random number of dbs to create
|
32
|
+
let(:db_names){ x.times.map{|y| "database_#{y}" } }
|
33
|
+
|
34
|
+
before do
|
35
|
+
db_names.collect do |db_name|
|
36
|
+
Apartment::Database.create(db_name)
|
37
|
+
Company.create :database => db_name
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
after do
|
42
|
+
db_names.each{ |db| Apartment::Database.drop(db) }
|
43
|
+
Company.delete_all
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#migrate" do
|
47
|
+
it "should migrate all databases" do
|
48
|
+
Apartment::Migrator.should_receive(:migrate).exactly(db_names.length).times
|
49
|
+
|
50
|
+
@rake['apartment:migrate'].invoke
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#rollback" do
|
55
|
+
it "should rollback all dbs" do
|
56
|
+
db_names.each do |name|
|
57
|
+
Apartment::Migrator.should_receive(:rollback).with(name, anything)
|
58
|
+
end
|
59
|
+
|
60
|
+
@rake['apartment:rollback'].invoke
|
61
|
+
@rake['apartment:migrate'].invoke # migrate again so that our next test 'seed' can run (requires migrations to be complete)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "apartment:seed" do
|
66
|
+
it "should seed all databases" do
|
67
|
+
Apartment::Database.should_receive(:seed).exactly(db_names.length).times
|
68
|
+
|
69
|
+
@rake['apartment:seed'].invoke
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Apartment::Database do
|
4
|
+
|
5
|
+
context "using postgresql" do
|
6
|
+
|
7
|
+
# See apartment.yml file in dummy app config
|
8
|
+
|
9
|
+
let(:config){ Apartment::Test.config['connections']['postgresql'].symbolize_keys }
|
10
|
+
let(:database){ "some_new_database" }
|
11
|
+
let(:database2){ "yet_another_database" }
|
12
|
+
|
13
|
+
before do
|
14
|
+
Apartment.use_postgres_schemas = true
|
15
|
+
ActiveRecord::Base.establish_connection config
|
16
|
+
Apartment::Test.load_schema # load the Rails schema in the public db schema
|
17
|
+
Apartment::Database.stub(:config).and_return config # Use postgresql database config for this test
|
18
|
+
@schema_search_path = ActiveRecord::Base.connection.schema_search_path
|
19
|
+
end
|
20
|
+
|
21
|
+
after do
|
22
|
+
Apartment::Test.reset
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#init" do
|
26
|
+
|
27
|
+
it "should process model exclusions" do
|
28
|
+
Apartment.configure do |config|
|
29
|
+
config.excluded_models = ["Company"]
|
30
|
+
end
|
31
|
+
|
32
|
+
Apartment::Database.init
|
33
|
+
|
34
|
+
Company.table_name.should == "public.companies"
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#adapter" do
|
40
|
+
before do
|
41
|
+
Apartment::Database.reload!
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should load postgresql adapter" do
|
45
|
+
Apartment::Database.adapter
|
46
|
+
Apartment::Adapters::PostgresqlAdapter.should be_a(Class)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should raise exception with invalid adapter specified" do
|
50
|
+
Apartment::Database.stub(:config).and_return config.merge(:adapter => 'unkown')
|
51
|
+
|
52
|
+
expect {
|
53
|
+
Apartment::Database.adapter
|
54
|
+
}.to raise_error
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
context "with schemas" do
|
60
|
+
|
61
|
+
before do
|
62
|
+
Apartment.configure do |config|
|
63
|
+
config.excluded_models = []
|
64
|
+
config.use_postgres_schemas = true
|
65
|
+
config.seed_after_create = true
|
66
|
+
end
|
67
|
+
Apartment::Database.create database
|
68
|
+
end
|
69
|
+
|
70
|
+
after do
|
71
|
+
Apartment::Test.drop_schema database
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#process" do
|
75
|
+
|
76
|
+
before do
|
77
|
+
Apartment::Database.create database2
|
78
|
+
end
|
79
|
+
|
80
|
+
after do
|
81
|
+
Apartment::Test.drop_schema database2
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should connect to new schema" do
|
85
|
+
Apartment::Database.process(database) do
|
86
|
+
Apartment::Database.current_database.should == database
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should reset connection to the previous db" do
|
91
|
+
Apartment::Database.switch(database2)
|
92
|
+
Apartment::Database.process(database)
|
93
|
+
Apartment::Database.current_database.should == database2
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should reset to previous schema if database is nil" do
|
97
|
+
Apartment::Database.switch(database)
|
98
|
+
Apartment::Database.process
|
99
|
+
Apartment::Database.current_database.should == database
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should set to public schema if database is nil" do
|
103
|
+
Apartment::Database.process do
|
104
|
+
Apartment::Database.current_database.should == @schema_search_path
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "#create" do
|
111
|
+
it "should create new postgres schema" do
|
112
|
+
ActiveRecord::Base.connection.execute("SELECT nspname FROM pg_namespace;").collect{|row| row['nspname']}.should include(database)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should seed data" do
|
116
|
+
Apartment::Database.switch database
|
117
|
+
User.count.should be > 0
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "#switch" do
|
122
|
+
|
123
|
+
let(:x){ rand(3) }
|
124
|
+
|
125
|
+
it "should connect to new schema" do
|
126
|
+
Apartment::Database.switch database
|
127
|
+
ActiveRecord::Base.connection.schema_search_path.should == database
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should fail with invalid schema" do
|
131
|
+
expect {
|
132
|
+
Apartment::Database.switch('some_nonexistent_schema')
|
133
|
+
}.to raise_error Apartment::SchemaNotFound
|
134
|
+
end
|
135
|
+
|
136
|
+
context "creating models" do
|
137
|
+
|
138
|
+
before do
|
139
|
+
Apartment::Database.create database2
|
140
|
+
end
|
141
|
+
|
142
|
+
after do
|
143
|
+
Apartment::Test.drop_schema database2
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should create a model instance in the current schema" do
|
147
|
+
Apartment::Database.switch database2
|
148
|
+
db2_count = User.count + x.times{ User.create }
|
149
|
+
|
150
|
+
Apartment::Database.switch database
|
151
|
+
db_count = User.count + x.times{ User.create }
|
152
|
+
|
153
|
+
Apartment::Database.switch database2
|
154
|
+
User.count.should == db2_count
|
155
|
+
|
156
|
+
Apartment::Database.switch database
|
157
|
+
User.count.should == db_count
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "with excluded models" do
|
162
|
+
|
163
|
+
before do
|
164
|
+
Apartment.configure do |config|
|
165
|
+
config.excluded_models = ["Company"]
|
166
|
+
end
|
167
|
+
Apartment::Database.init
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should ignore excluded models" do
|
171
|
+
Apartment::Database.switch database
|
172
|
+
Company.table_name.should include('public')
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should create excluded models in public schema" do
|
176
|
+
Apartment::Database.reset # ensure we're on public schema
|
177
|
+
count = Company.count + x.times{ Company.create }
|
178
|
+
|
179
|
+
Apartment::Database.switch database
|
180
|
+
x.times{ Company.create }
|
181
|
+
Company.count.should == count + x
|
182
|
+
Apartment::Database.reset
|
183
|
+
Company.count.should == count + x
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
describe "#current_database" do
|
190
|
+
|
191
|
+
it "should return the current schema search path" do
|
192
|
+
Apartment::Database.switch database
|
193
|
+
Apartment::Database.current_database.should == database
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'delayed_job'
|
3
|
+
Delayed::Worker.guess_backend
|
4
|
+
|
5
|
+
describe Apartment::Delayed do
|
6
|
+
|
7
|
+
# See apartment.yml file in dummy app config
|
8
|
+
|
9
|
+
let(:config){ Apartment::Test.config['connections']['postgresql'].symbolize_keys }
|
10
|
+
let(:database){ "some_new_database" }
|
11
|
+
let(:database2){ "another_db" }
|
12
|
+
|
13
|
+
before do
|
14
|
+
ActiveRecord::Base.establish_connection config
|
15
|
+
Apartment::Test.load_schema # load the Rails schema in the public db schema
|
16
|
+
Apartment::Database.stub(:config).and_return config # Use postgresql database config for this test
|
17
|
+
@schema_search_path = ActiveRecord::Base.connection.schema_search_path
|
18
|
+
|
19
|
+
Apartment.configure do |config|
|
20
|
+
config.use_postgres_schemas = true
|
21
|
+
end
|
22
|
+
|
23
|
+
Apartment::Database.create database
|
24
|
+
Apartment::Database.create database2
|
25
|
+
end
|
26
|
+
|
27
|
+
after do
|
28
|
+
Apartment::Test.drop_schema database
|
29
|
+
Apartment::Test.drop_schema database2
|
30
|
+
Apartment::Test.reset
|
31
|
+
end
|
32
|
+
|
33
|
+
describe Apartment::Delayed::Job do
|
34
|
+
context "#enqueue" do
|
35
|
+
|
36
|
+
before do
|
37
|
+
Apartment::Database.reset
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should queue up jobs in the public schema" do
|
41
|
+
dj_count = Delayed::Job.count
|
42
|
+
Apartment::Database.switch database
|
43
|
+
Apartment::Delayed::Job.enqueue FakeDjClass.new
|
44
|
+
Apartment::Database.reset
|
45
|
+
|
46
|
+
Delayed::Job.count.should == dj_count + 1
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should not queue jobs in the current schema" do
|
50
|
+
Apartment::Database.switch database
|
51
|
+
expect {
|
52
|
+
Apartment::Delayed::Job.enqueue FakeDjClass.new
|
53
|
+
}.to_not change(Delayed::Job, :count) # because we will still be on the `database` schema, not public
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe Apartment::Delayed::Requirements do
|
59
|
+
|
60
|
+
before do
|
61
|
+
Apartment::Database.switch database
|
62
|
+
User.send(:include, Apartment::Delayed::Requirements)
|
63
|
+
User.create
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should initialize a database attribute on a class" do
|
67
|
+
user = User.first
|
68
|
+
user.database.should == database
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should not overwrite any previous after_initialize declarations" do
|
72
|
+
User.class_eval do
|
73
|
+
after_find :set_name
|
74
|
+
|
75
|
+
def set_name
|
76
|
+
self.name = "Some Name"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
user = User.first
|
81
|
+
user.database.should == database
|
82
|
+
user.name.should == "Some Name"
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should set the db on a new record before it saves" do
|
86
|
+
user = User.create
|
87
|
+
user.database.should == database
|
88
|
+
end
|
89
|
+
|
90
|
+
context "serialization" do
|
91
|
+
it "should serialize the proper database attribute" do
|
92
|
+
user_yaml = User.first.to_yaml
|
93
|
+
Apartment::Database.switch database2
|
94
|
+
user = YAML.load user_yaml
|
95
|
+
user.database.should == database
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|