apartment 1.0.2 → 1.1.0

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +5 -8
  4. data/Gemfile +1 -0
  5. data/README.md +79 -4
  6. data/apartment.gemspec +2 -2
  7. data/gemfiles/rails_3_2.gemfile +2 -0
  8. data/lib/apartment.rb +22 -2
  9. data/lib/apartment/adapters/abstract_adapter.rb +70 -16
  10. data/lib/apartment/adapters/abstract_jdbc_adapter.rb +4 -9
  11. data/lib/apartment/adapters/jdbc_mysql_adapter.rb +2 -13
  12. data/lib/apartment/adapters/jdbc_postgresql_adapter.rb +5 -16
  13. data/lib/apartment/adapters/mysql2_adapter.rb +8 -19
  14. data/lib/apartment/adapters/postgresql_adapter.rb +16 -41
  15. data/lib/apartment/adapters/sqlite3_adapter.rb +6 -3
  16. data/lib/apartment/elevators/first_subdomain.rb +1 -1
  17. data/lib/apartment/elevators/generic.rb +5 -3
  18. data/lib/apartment/version.rb +1 -1
  19. data/lib/generators/apartment/install/templates/apartment.rb +26 -1
  20. data/lib/tasks/apartment.rake +0 -1
  21. data/spec/adapters/jdbc_mysql_adapter_spec.rb +1 -1
  22. data/spec/adapters/jdbc_postgresql_adapter_spec.rb +1 -1
  23. data/spec/adapters/mysql2_adapter_spec.rb +2 -1
  24. data/spec/adapters/postgresql_adapter_spec.rb +1 -0
  25. data/spec/adapters/sqlite3_adapter_spec.rb +56 -0
  26. data/spec/apartment_spec.rb +2 -2
  27. data/spec/examples/connection_adapter_examples.rb +1 -1
  28. data/spec/examples/generic_adapter_custom_configuration_example.rb +90 -0
  29. data/spec/examples/generic_adapter_examples.rb +15 -15
  30. data/spec/examples/schema_adapter_examples.rb +25 -25
  31. data/spec/integration/apartment_rake_integration_spec.rb +4 -4
  32. data/spec/integration/query_caching_spec.rb +2 -2
  33. data/spec/spec_helper.rb +11 -0
  34. data/spec/support/apartment_helpers.rb +8 -2
  35. data/spec/support/setup.rb +3 -3
  36. data/spec/tasks/apartment_rake_spec.rb +11 -11
  37. data/spec/tenant_spec.rb +12 -12
  38. data/spec/unit/config_spec.rb +53 -23
  39. data/spec/unit/elevators/domain_spec.rb +4 -4
  40. data/spec/unit/elevators/first_subdomain_spec.rb +7 -2
  41. data/spec/unit/elevators/generic_spec.rb +19 -2
  42. data/spec/unit/elevators/host_hash_spec.rb +2 -2
  43. data/spec/unit/elevators/subdomain_spec.rb +6 -6
  44. data/spec/unit/migrator_spec.rb +1 -1
  45. data/spec/unit/reloader_spec.rb +2 -2
  46. metadata +11 -9
@@ -14,13 +14,13 @@ shared_examples_for "a generic apartment adapter" do
14
14
  describe "#create" do
15
15
 
16
16
  it "should create the new databases" do
17
- tenant_names.should include(db1)
18
- tenant_names.should include(db2)
17
+ expect(tenant_names).to include(db1)
18
+ expect(tenant_names).to include(db2)
19
19
  end
20
20
 
21
21
  it "should load schema.rb to new schema" do
22
22
  subject.switch(db1) do
23
- connection.tables.should include('companies')
23
+ expect(connection.tables).to include('companies')
24
24
  end
25
25
  end
26
26
 
@@ -31,32 +31,32 @@ shared_examples_for "a generic apartment adapter" do
31
31
 
32
32
  subject.create(db2) do
33
33
  @count = User.count
34
- subject.current.should == db2
34
+ expect(subject.current).to eq(db2)
35
35
  User.create
36
36
  end
37
37
 
38
- subject.current.should_not == db2
38
+ expect(subject.current).not_to eq(db2)
39
39
 
40
- subject.switch(db2){ User.count.should == @count + 1 }
40
+ subject.switch(db2){ expect(User.count).to eq(@count + 1) }
41
41
  end
42
42
  end
43
43
 
44
44
  describe "#drop" do
45
45
  it "should remove the db" do
46
46
  subject.drop db1
47
- tenant_names.should_not include(db1)
47
+ expect(tenant_names).not_to include(db1)
48
48
  end
49
49
  end
50
50
 
51
51
  describe "#switch!" do
52
52
  it "should connect to new db" do
53
53
  subject.switch!(db1)
54
- subject.current.should == db1
54
+ expect(subject.current).to eq(db1)
55
55
  end
56
56
 
57
57
  it "should reset connection if database is nil" do
58
58
  subject.switch!
59
- subject.current.should == default_tenant
59
+ expect(subject.current).to eq(default_tenant)
60
60
  end
61
61
 
62
62
  it "should raise an error if database is invalid" do
@@ -69,9 +69,9 @@ shared_examples_for "a generic apartment adapter" do
69
69
  describe "#switch" do
70
70
  it "connects and resets the tenant" do
71
71
  subject.switch(db1) do
72
- subject.current.should == db1
72
+ expect(subject.current).to eq(db1)
73
73
  end
74
- subject.current.should == default_tenant
74
+ expect(subject.current).to eq(default_tenant)
75
75
  end
76
76
 
77
77
  # We're often finding when using Apartment in tests, the `current` (ie the previously connect to db)
@@ -88,7 +88,7 @@ shared_examples_for "a generic apartment adapter" do
88
88
  expect(Apartment::Deprecation).to receive(:warn)
89
89
 
90
90
  subject.switch(db1)
91
- subject.current.should == db1
91
+ expect(subject.current).to eq(db1)
92
92
  end
93
93
  end
94
94
 
@@ -97,7 +97,7 @@ shared_examples_for "a generic apartment adapter" do
97
97
  expect(Apartment::Deprecation).to receive(:warn)
98
98
 
99
99
  subject.process(db1) do
100
- subject.current.should == db1
100
+ expect(subject.current).to eq(db1)
101
101
  end
102
102
  end
103
103
  end
@@ -106,14 +106,14 @@ shared_examples_for "a generic apartment adapter" do
106
106
  it "should reset connection" do
107
107
  subject.switch!(db1)
108
108
  subject.reset
109
- subject.current.should == default_tenant
109
+ expect(subject.current).to eq(default_tenant)
110
110
  end
111
111
  end
112
112
 
113
113
  describe "#current" do
114
114
  it "should return the current db name" do
115
115
  subject.switch!(db1)
116
- subject.current.should == db1
116
+ expect(subject.current).to eq(db1)
117
117
  end
118
118
  end
119
119
 
@@ -18,7 +18,7 @@ shared_examples_for "a schema based apartment adapter" do
18
18
  it "should process model exclusions" do
19
19
  Apartment::Tenant.init
20
20
 
21
- Company.table_name.should == "public.companies"
21
+ expect(Company.table_name).to eq("public.companies")
22
22
  end
23
23
 
24
24
  context "with a default_schema", :default_schema => true do
@@ -26,20 +26,20 @@ shared_examples_for "a schema based apartment adapter" do
26
26
  it "should set the proper table_name on excluded_models" do
27
27
  Apartment::Tenant.init
28
28
 
29
- Company.table_name.should == "#{default_schema}.companies"
29
+ expect(Company.table_name).to eq("#{default_schema}.companies")
30
30
  end
31
31
 
32
32
  it 'sets the search_path correctly' do
33
33
  Apartment::Tenant.init
34
34
 
35
- User.connection.schema_search_path.should =~ %r|#{default_schema}|
35
+ expect(User.connection.schema_search_path).to match(%r|#{default_schema}|)
36
36
  end
37
37
  end
38
38
 
39
39
  context "persistent_schemas", :persistent_schemas => true do
40
40
  it "sets the persistent schemas in the schema_search_path" do
41
41
  Apartment::Tenant.init
42
- connection.schema_search_path.should end_with persistent_schemas.map { |schema| %{"#{schema}"} }.join(', ')
42
+ expect(connection.schema_search_path).to end_with persistent_schemas.map { |schema| %{"#{schema}"} }.join(', ')
43
43
  end
44
44
  end
45
45
  end
@@ -51,7 +51,7 @@ shared_examples_for "a schema based apartment adapter" do
51
51
 
52
52
  it "should load schema.rb to new schema" do
53
53
  connection.schema_search_path = schema1
54
- connection.tables.should include('companies')
54
+ expect(connection.tables).to include('companies')
55
55
  end
56
56
 
57
57
  it "should yield to block if passed and reset" do
@@ -61,13 +61,13 @@ shared_examples_for "a schema based apartment adapter" do
61
61
 
62
62
  subject.create(schema2) do
63
63
  @count = User.count
64
- connection.schema_search_path.should start_with %{"#{schema2}"}
64
+ expect(connection.schema_search_path).to start_with %{"#{schema2}"}
65
65
  User.create
66
66
  end
67
67
 
68
- connection.schema_search_path.should_not start_with %{"#{schema2}"}
68
+ expect(connection.schema_search_path).not_to start_with %{"#{schema2}"}
69
69
 
70
- subject.switch(schema2){ User.count.should == @count + 1 }
70
+ subject.switch(schema2){ expect(User.count).to eq(@count + 1) }
71
71
  end
72
72
 
73
73
  context "numeric database names" do
@@ -76,7 +76,7 @@ shared_examples_for "a schema based apartment adapter" do
76
76
  expect {
77
77
  subject.create(db)
78
78
  }.to_not raise_error
79
- tenant_names.should include(db.to_s)
79
+ expect(tenant_names).to include(db.to_s)
80
80
  end
81
81
 
82
82
  after{ subject.drop(db) }
@@ -99,7 +99,7 @@ shared_examples_for "a schema based apartment adapter" do
99
99
  expect {
100
100
  subject.drop(db)
101
101
  }.to_not raise_error
102
- tenant_names.should_not include(db.to_s)
102
+ expect(tenant_names).not_to include(db.to_s)
103
103
  end
104
104
 
105
105
  after { subject.drop(db) rescue nil }
@@ -109,10 +109,10 @@ shared_examples_for "a schema based apartment adapter" do
109
109
  describe "#switch" do
110
110
  it "connects and resets" do
111
111
  subject.switch(schema1) do
112
- connection.schema_search_path.should start_with %{"#{schema1}"}
112
+ expect(connection.schema_search_path).to start_with %{"#{schema1}"}
113
113
  end
114
114
 
115
- connection.schema_search_path.should start_with %{"#{public_schema}"}
115
+ expect(connection.schema_search_path).to start_with %{"#{public_schema}"}
116
116
  end
117
117
  end
118
118
 
@@ -120,14 +120,14 @@ shared_examples_for "a schema based apartment adapter" do
120
120
  it "should reset connection" do
121
121
  subject.switch!(schema1)
122
122
  subject.reset
123
- connection.schema_search_path.should start_with %{"#{public_schema}"}
123
+ expect(connection.schema_search_path).to start_with %{"#{public_schema}"}
124
124
  end
125
125
 
126
126
  context "with default_schema", :default_schema => true do
127
127
  it "should reset to the default schema" do
128
128
  subject.switch!(schema1)
129
129
  subject.reset
130
- connection.schema_search_path.should start_with %{"#{default_schema}"}
130
+ expect(connection.schema_search_path).to start_with %{"#{default_schema}"}
131
131
  end
132
132
  end
133
133
 
@@ -138,13 +138,13 @@ shared_examples_for "a schema based apartment adapter" do
138
138
  end
139
139
 
140
140
  it "maintains the persistent schemas in the schema_search_path" do
141
- connection.schema_search_path.should end_with persistent_schemas.map { |schema| %{"#{schema}"} }.join(', ')
141
+ expect(connection.schema_search_path).to end_with persistent_schemas.map { |schema| %{"#{schema}"} }.join(', ')
142
142
  end
143
143
 
144
144
  context "with default_schema", :default_schema => true do
145
145
  it "prioritizes the switched schema to front of schema_search_path" do
146
146
  subject.reset # need to re-call this as the default_schema wasn't set at the time that the above reset ran
147
- connection.schema_search_path.should start_with %{"#{default_schema}"}
147
+ expect(connection.schema_search_path).to start_with %{"#{default_schema}"}
148
148
  end
149
149
  end
150
150
  end
@@ -153,12 +153,12 @@ shared_examples_for "a schema based apartment adapter" do
153
153
  describe "#switch!" do
154
154
  it "should connect to new schema" do
155
155
  subject.switch!(schema1)
156
- connection.schema_search_path.should start_with %{"#{schema1}"}
156
+ expect(connection.schema_search_path).to start_with %{"#{schema1}"}
157
157
  end
158
158
 
159
159
  it "should reset connection if database is nil" do
160
160
  subject.switch!
161
- connection.schema_search_path.should == %{"#{public_schema}"}
161
+ expect(connection.schema_search_path).to eq(%{"#{public_schema}"})
162
162
  end
163
163
 
164
164
  it "should raise an error if schema is invalid" do
@@ -176,7 +176,7 @@ shared_examples_for "a schema based apartment adapter" do
176
176
  subject.switch!(db)
177
177
  }.to_not raise_error
178
178
 
179
- connection.schema_search_path.should start_with %{"#{db.to_s}"}
179
+ expect(connection.schema_search_path).to start_with %{"#{db.to_s}"}
180
180
  end
181
181
 
182
182
  after{ subject.drop(db) }
@@ -188,11 +188,11 @@ shared_examples_for "a schema based apartment adapter" do
188
188
  end
189
189
 
190
190
  it "should switch out the default schema rather than public" do
191
- connection.schema_search_path.should_not include default_schema
191
+ expect(connection.schema_search_path).not_to include default_schema
192
192
  end
193
193
 
194
194
  it "should still switch to the switched schema" do
195
- connection.schema_search_path.should start_with %{"#{schema1}"}
195
+ expect(connection.schema_search_path).to start_with %{"#{schema1}"}
196
196
  end
197
197
  end
198
198
 
@@ -201,11 +201,11 @@ shared_examples_for "a schema based apartment adapter" do
201
201
  before{ subject.switch!(schema1) }
202
202
 
203
203
  it "maintains the persistent schemas in the schema_search_path" do
204
- connection.schema_search_path.should end_with persistent_schemas.map { |schema| %{"#{schema}"} }.join(', ')
204
+ expect(connection.schema_search_path).to end_with persistent_schemas.map { |schema| %{"#{schema}"} }.join(', ')
205
205
  end
206
206
 
207
207
  it "prioritizes the switched schema to front of schema_search_path" do
208
- connection.schema_search_path.should start_with %{"#{schema1}"}
208
+ expect(connection.schema_search_path).to start_with %{"#{schema1}"}
209
209
  end
210
210
  end
211
211
  end
@@ -213,13 +213,13 @@ shared_examples_for "a schema based apartment adapter" do
213
213
  describe "#current" do
214
214
  it "should return the current schema name" do
215
215
  subject.switch!(schema1)
216
- subject.current.should == schema1
216
+ expect(subject.current).to eq(schema1)
217
217
  end
218
218
 
219
219
  context "persistent_schemas", :persistent_schemas => true do
220
220
  it "should exlude persistent_schemas" do
221
221
  subject.switch!(schema1)
222
- subject.current.should == schema1
222
+ expect(subject.current).to eq(schema1)
223
223
  end
224
224
  end
225
225
  end
@@ -33,7 +33,7 @@ describe "apartment rake tasks", database: :postgresql do
33
33
 
34
34
  let(:x){ 1 + rand(5) } # random number of dbs to create
35
35
  let(:db_names){ x.times.map{ Apartment::Test.next_db } }
36
- let!(:company_count){ Company.count + db_names.length }
36
+ let!(:company_count){ db_names.length }
37
37
 
38
38
  before do
39
39
  db_names.collect do |db_name|
@@ -49,7 +49,7 @@ describe "apartment rake tasks", database: :postgresql do
49
49
 
50
50
  describe "#migrate" do
51
51
  it "should migrate all databases" do
52
- ActiveRecord::Migrator.should_receive(:migrate).exactly(company_count).times
52
+ expect(ActiveRecord::Migrator).to receive(:migrate).exactly(company_count).times
53
53
 
54
54
  @rake['apartment:migrate'].invoke
55
55
  end
@@ -57,7 +57,7 @@ describe "apartment rake tasks", database: :postgresql do
57
57
 
58
58
  describe "#rollback" do
59
59
  it "should rollback all dbs" do
60
- ActiveRecord::Migrator.should_receive(:rollback).exactly(company_count).times
60
+ expect(ActiveRecord::Migrator).to receive(:rollback).exactly(company_count).times
61
61
 
62
62
  @rake['apartment:rollback'].invoke
63
63
  end
@@ -65,7 +65,7 @@ describe "apartment rake tasks", database: :postgresql do
65
65
 
66
66
  describe "apartment:seed" do
67
67
  it "should seed all databases" do
68
- Apartment::Tenant.should_receive(:seed).exactly(company_count).times
68
+ expect(Apartment::Tenant).to receive(:seed).exactly(company_count).times
69
69
 
70
70
  @rake['apartment:seed'].invoke
71
71
  end
@@ -33,9 +33,9 @@ describe 'query caching' do
33
33
  ActiveRecord::Base.connection.enable_query_cache!
34
34
 
35
35
  Apartment::Tenant.switch! db_names.first
36
- User.find_by_name(db_names.first).name.should == db_names.first
36
+ expect(User.find_by_name(db_names.first).name).to eq(db_names.first)
37
37
 
38
38
  Apartment::Tenant.switch! db_names.last
39
- User.find_by_name(db_names.first).should be_nil
39
+ expect(User.find_by_name(db_names.first)).to be_nil
40
40
  end
41
41
  end
@@ -32,6 +32,17 @@ RSpec.configure do |config|
32
32
  config.after(:all) do
33
33
  `git checkout -- spec/dummy/db/schema.rb`
34
34
  end
35
+
36
+ # rspec-rails 3 will no longer automatically infer an example group's spec type
37
+ # from the file location. You can explicitly opt-in to the feature using this
38
+ # config option.
39
+ # To explicitly tag specs without using automatic inference, set the `:type`
40
+ # metadata manually:
41
+ #
42
+ # describe ThingsController, :type => :controller do
43
+ # # Equivalent to being in spec/controllers
44
+ # end
45
+ config.infer_spec_type_from_file_location!
35
46
  end
36
47
 
37
48
  # Load shared examples, must happen after configure for RSpec 3
@@ -15,6 +15,12 @@ module Apartment
15
15
  "db%d" % @x += 1
16
16
  end
17
17
 
18
+ def reset_table_names
19
+ Apartment.excluded_models.each do |model|
20
+ model.constantize.reset_table_name
21
+ end
22
+ end
23
+
18
24
  def drop_schema(schema)
19
25
  ActiveRecord::Base.connection.execute("DROP SCHEMA IF EXISTS #{schema} CASCADE") rescue true
20
26
  end
@@ -28,7 +34,7 @@ module Apartment
28
34
  def load_schema(version = 3)
29
35
  file = File.expand_path("../../schemas/v#{version}.rb", __FILE__)
30
36
 
31
- silence_stream(STDOUT){ load(file) }
37
+ silence_warnings{ load(file) }
32
38
  end
33
39
 
34
40
  def migrate
@@ -40,4 +46,4 @@ module Apartment
40
46
  end
41
47
 
42
48
  end
43
- end
49
+ end
@@ -14,7 +14,7 @@ module Apartment
14
14
  around(:each) do |example|
15
15
 
16
16
  def config
17
- db = example.metadata.fetch(:database, :postgresql)
17
+ db = RSpec.current_example.metadata.fetch(:database, :postgresql)
18
18
 
19
19
  Apartment::Test.config['connections'][db.to_s].symbolize_keys
20
20
  end
@@ -22,6 +22,7 @@ module Apartment
22
22
  # before
23
23
  Apartment::Tenant.reload!(config)
24
24
  ActiveRecord::Base.establish_connection config
25
+ Apartment::Test.reset_table_names
25
26
 
26
27
  example.run
27
28
 
@@ -34,9 +35,8 @@ module Apartment
34
35
 
35
36
  Apartment.connection_class.remove_connection(klass)
36
37
  klass.clear_all_connections!
37
- klass.reset_table_name
38
38
  end
39
-
39
+ Apartment::Test.reset_table_names
40
40
  Apartment.reset
41
41
  Apartment::Tenant.reload!
42
42
  end
@@ -34,16 +34,16 @@ describe "apartment rake tasks" do
34
34
  let(:tenant_count){ tenant_names.length }
35
35
 
36
36
  before do
37
- Apartment.stub(:tenant_names).and_return tenant_names
37
+ allow(Apartment).to receive(:tenant_names).and_return tenant_names
38
38
  end
39
39
 
40
40
  describe "apartment:migrate" do
41
41
  before do
42
- ActiveRecord::Migrator.stub(:migrate) # don't care about this
42
+ allow(ActiveRecord::Migrator).to receive(:migrate) # don't care about this
43
43
  end
44
44
 
45
45
  it "should migrate public and all multi-tenant dbs" do
46
- Apartment::Migrator.should_receive(:migrate).exactly(tenant_count).times
46
+ expect(Apartment::Migrator).to receive(:migrate).exactly(tenant_count).times
47
47
  @rake['apartment:migrate'].invoke
48
48
  end
49
49
  end
@@ -56,9 +56,9 @@ describe "apartment rake tasks" do
56
56
  end
57
57
 
58
58
  it "requires a version to migrate to" do
59
- lambda{
59
+ expect{
60
60
  @rake['apartment:migrate:up'].invoke
61
- }.should raise_error("VERSION is required")
61
+ }.to raise_error("VERSION is required")
62
62
  end
63
63
  end
64
64
 
@@ -69,7 +69,7 @@ describe "apartment rake tasks" do
69
69
  end
70
70
 
71
71
  it "migrates up to a specific version" do
72
- Apartment::Migrator.should_receive(:run).with(:up, anything, version.to_i).exactly(tenant_count).times
72
+ expect(Apartment::Migrator).to receive(:run).with(:up, anything, version.to_i).exactly(tenant_count).times
73
73
  @rake['apartment:migrate:up'].invoke
74
74
  end
75
75
  end
@@ -83,9 +83,9 @@ describe "apartment rake tasks" do
83
83
  end
84
84
 
85
85
  it "requires a version to migrate to" do
86
- lambda{
86
+ expect{
87
87
  @rake['apartment:migrate:down'].invoke
88
- }.should raise_error("VERSION is required")
88
+ }.to raise_error("VERSION is required")
89
89
  end
90
90
  end
91
91
 
@@ -96,7 +96,7 @@ describe "apartment rake tasks" do
96
96
  end
97
97
 
98
98
  it "migrates up to a specific version" do
99
- Apartment::Migrator.should_receive(:run).with(:down, anything, version.to_i).exactly(tenant_count).times
99
+ expect(Apartment::Migrator).to receive(:run).with(:down, anything, version.to_i).exactly(tenant_count).times
100
100
  @rake['apartment:migrate:down'].invoke
101
101
  end
102
102
  end
@@ -106,12 +106,12 @@ describe "apartment rake tasks" do
106
106
  let(:step){ '3' }
107
107
 
108
108
  it "should rollback dbs" do
109
- Apartment::Migrator.should_receive(:rollback).exactly(tenant_count).times
109
+ expect(Apartment::Migrator).to receive(:rollback).exactly(tenant_count).times
110
110
  @rake['apartment:rollback'].invoke
111
111
  end
112
112
 
113
113
  it "should rollback dbs STEP amt" do
114
- Apartment::Migrator.should_receive(:rollback).with(anything, step.to_i).exactly(tenant_count).times
114
+ expect(Apartment::Migrator).to receive(:rollback).with(anything, step.to_i).exactly(tenant_count).times
115
115
  ENV['STEP'] = step
116
116
  @rake['apartment:rollback'].invoke
117
117
  end