apartment 0.23.2 → 0.24.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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.md +12 -1
  3. data/README.md +16 -13
  4. data/Rakefile +6 -1
  5. data/TODO.md +9 -14
  6. data/lib/apartment.rb +17 -3
  7. data/lib/apartment/adapters/abstract_adapter.rb +53 -44
  8. data/lib/apartment/adapters/jdbc_postgresql_adapter.rb +9 -9
  9. data/lib/apartment/adapters/mysql2_adapter.rb +15 -15
  10. data/lib/apartment/adapters/postgresql_adapter.rb +26 -18
  11. data/lib/apartment/adapters/sqlite3_adapter.rb +13 -13
  12. data/lib/apartment/database.rb +2 -2
  13. data/lib/apartment/elevators/host_hash.rb +3 -3
  14. data/lib/apartment/elevators/subdomain.rb +2 -3
  15. data/lib/apartment/migrator.rb +3 -3
  16. data/lib/apartment/railtie.rb +2 -1
  17. data/lib/apartment/tasks/enhancements.rb +26 -0
  18. data/lib/apartment/version.rb +1 -1
  19. data/lib/generators/apartment/install/templates/apartment.rb +13 -8
  20. data/lib/tasks/apartment.rake +34 -38
  21. data/spec/adapters/jdbc_mysql_adapter_spec.rb +2 -4
  22. data/spec/adapters/jdbc_postgresql_adapter_spec.rb +6 -6
  23. data/spec/adapters/mysql2_adapter_spec.rb +5 -5
  24. data/spec/adapters/postgresql_adapter_spec.rb +6 -6
  25. data/spec/adapters/sqlite3_adapter_spec.rb +2 -2
  26. data/spec/database_spec.rb +2 -2
  27. data/spec/dummy/config/initializers/apartment.rb +2 -2
  28. data/spec/examples/connection_adapter_examples.rb +2 -2
  29. data/spec/examples/generic_adapter_examples.rb +15 -15
  30. data/spec/examples/schema_adapter_examples.rb +6 -6
  31. data/spec/integration/apartment_rake_integration_spec.rb +4 -4
  32. data/spec/integration/query_caching_spec.rb +2 -2
  33. data/spec/support/requirements.rb +2 -5
  34. data/spec/tasks/apartment_rake_spec.rb +8 -9
  35. data/spec/unit/config_spec.rb +17 -10
  36. data/spec/unit/elevators/subdomain_spec.rb +26 -6
  37. metadata +3 -2
@@ -7,15 +7,13 @@ if defined?(JRUBY_VERSION)
7
7
 
8
8
  subject { Apartment::Database.jdbc_mysql_adapter config.symbolize_keys }
9
9
 
10
- def database_names
10
+ def tenant_names
11
11
  ActiveRecord::Base.connection.execute("SELECT schema_name FROM information_schema.schemata").collect { |row| row['schema_name'] }
12
12
  end
13
13
 
14
- let(:default_database) { subject.process { ActiveRecord::Base.connection.current_database } }
14
+ let(:default_tenant) { subject.process { ActiveRecord::Base.connection.current_database } }
15
15
 
16
16
  it_should_behave_like "a generic apartment adapter"
17
17
  it_should_behave_like "a connection based apartment adapter"
18
-
19
18
  end
20
-
21
19
  end
@@ -11,12 +11,12 @@ if defined?(JRUBY_VERSION)
11
11
 
12
12
  before { Apartment.use_schemas = true }
13
13
 
14
- # Not sure why, but somehow using let(:database_names) memoizes for the whole example group, not just each test
15
- def database_names
14
+ # Not sure why, but somehow using let(:tenant_names) memoizes for the whole example group, not just each test
15
+ def tenant_names
16
16
  ActiveRecord::Base.connection.execute("SELECT nspname FROM pg_namespace;").collect { |row| row['nspname'] }
17
17
  end
18
18
 
19
- let(:default_database) { subject.process { ActiveRecord::Base.connection.schema_search_path.gsub('"', '') } }
19
+ let(:default_tenant) { subject.process { ActiveRecord::Base.connection.schema_search_path.gsub('"', '') } }
20
20
 
21
21
  it_should_behave_like "a generic apartment adapter"
22
22
  it_should_behave_like "a schema based apartment adapter"
@@ -26,12 +26,12 @@ if defined?(JRUBY_VERSION)
26
26
 
27
27
  before { Apartment.use_schemas = false }
28
28
 
29
- # Not sure why, but somehow using let(:database_names) memoizes for the whole example group, not just each test
30
- def database_names
29
+ # Not sure why, but somehow using let(:tenant_names) memoizes for the whole example group, not just each test
30
+ def tenant_names
31
31
  connection.execute("select datname from pg_database;").collect { |row| row['datname'] }
32
32
  end
33
33
 
34
- let(:default_database) { subject.process { ActiveRecord::Base.connection.current_database } }
34
+ let(:default_tenant) { subject.process { ActiveRecord::Base.connection.current_database } }
35
35
 
36
36
  it_should_behave_like "a generic apartment adapter"
37
37
  it_should_behave_like "a connection based apartment adapter"
@@ -6,19 +6,19 @@ describe Apartment::Adapters::Mysql2Adapter, database: :mysql do
6
6
 
7
7
  subject(:adapter){ Apartment::Database.mysql2_adapter config }
8
8
 
9
- def database_names
9
+ def tenant_names
10
10
  ActiveRecord::Base.connection.execute("SELECT schema_name FROM information_schema.schemata").collect { |row| row[0] }
11
11
  end
12
12
 
13
- let(:default_database) { subject.process { ActiveRecord::Base.connection.current_database } }
13
+ let(:default_tenant) { subject.process { ActiveRecord::Base.connection.current_database } }
14
14
 
15
15
  context "using - the equivalent of - schemas" do
16
16
  before { Apartment.use_schemas = true }
17
17
 
18
18
  it_should_behave_like "a generic apartment adapter"
19
19
 
20
- describe "#default_database" do
21
- its(:default_database){ should == config[:database] }
20
+ describe "#default_tenant" do
21
+ its(:default_tenant){ should == config[:database] }
22
22
  end
23
23
 
24
24
  describe "#init" do
@@ -33,7 +33,7 @@ describe Apartment::Adapters::Mysql2Adapter, database: :mysql do
33
33
  it "should process model exclusions" do
34
34
  Apartment::Database.init
35
35
 
36
- Company.table_name.should == "#{default_database}.companies"
36
+ Company.table_name.should == "#{default_tenant}.companies"
37
37
  end
38
38
  end
39
39
  end
@@ -10,12 +10,12 @@ describe Apartment::Adapters::PostgresqlAdapter, database: :postgresql do
10
10
 
11
11
  before{ Apartment.use_schemas = true }
12
12
 
13
- # Not sure why, but somehow using let(:database_names) memoizes for the whole example group, not just each test
14
- def database_names
13
+ # Not sure why, but somehow using let(:tenant_names) memoizes for the whole example group, not just each test
14
+ def tenant_names
15
15
  ActiveRecord::Base.connection.execute("SELECT nspname FROM pg_namespace;").collect { |row| row['nspname'] }
16
16
  end
17
17
 
18
- let(:default_database) { subject.process { ActiveRecord::Base.connection.schema_search_path.gsub('"', '') } }
18
+ let(:default_tenant) { subject.process { ActiveRecord::Base.connection.schema_search_path.gsub('"', '') } }
19
19
 
20
20
  it_should_behave_like "a generic apartment adapter"
21
21
  it_should_behave_like "a schema based apartment adapter"
@@ -25,12 +25,12 @@ describe Apartment::Adapters::PostgresqlAdapter, database: :postgresql do
25
25
 
26
26
  before{ Apartment.use_schemas = false }
27
27
 
28
- # Not sure why, but somehow using let(:database_names) memoizes for the whole example group, not just each test
29
- def database_names
28
+ # Not sure why, but somehow using let(:tenant_names) memoizes for the whole example group, not just each test
29
+ def tenant_names
30
30
  connection.execute("select datname from pg_database;").collect { |row| row['datname'] }
31
31
  end
32
32
 
33
- let(:default_database) { subject.process { ActiveRecord::Base.connection.current_database } }
33
+ let(:default_tenant) { subject.process { ActiveRecord::Base.connection.current_database } }
34
34
 
35
35
  it_should_behave_like "a generic apartment adapter"
36
36
  it_should_behave_like "a connection based apartment adapter"
@@ -7,12 +7,12 @@ describe Apartment::Adapters::Sqlite3Adapter, database: :sqlite do
7
7
  subject{ Apartment::Database.sqlite3_adapter config }
8
8
 
9
9
  context "using connections" do
10
- def database_names
10
+ def tenant_names
11
11
  db_dir = File.expand_path("../../dummy/db", __FILE__)
12
12
  Dir.glob("#{db_dir}/*.sqlite3").map { |file| File.basename(file, '.sqlite3') }
13
13
  end
14
14
 
15
- let(:default_database) do
15
+ let(:default_tenant) do
16
16
  subject.process { File.basename(Apartment::Test.config['connections']['sqlite']['database'], '.sqlite3') }
17
17
  end
18
18
 
@@ -87,9 +87,9 @@ describe Apartment::Database do
87
87
 
88
88
  it 'has a threadsafe adapter' do
89
89
  subject.switch(db1)
90
- thread = Thread.new { subject.current_database.should == Apartment.default_schema }
90
+ thread = Thread.new { subject.current_tenant.should == Apartment.default_schema }
91
91
  thread.join
92
- subject.current_database.should == db1
92
+ subject.current_tenant.should == db1
93
93
  end
94
94
  end
95
95
  end
@@ -1,4 +1,4 @@
1
1
  Apartment.configure do |config|
2
2
  config.excluded_models = ["Company"]
3
- config.database_names = lambda{ Company.pluck(:database) }
4
- end
3
+ config.tenant_names = lambda{ Company.pluck(:database) }
4
+ end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  shared_examples_for "a connection based apartment adapter" do
4
4
  include Apartment::Spec::AdapterRequirements
5
5
 
6
- let(:default_database){ subject.process{ ActiveRecord::Base.connection.current_database } }
6
+ let(:default_tenant){ subject.process{ ActiveRecord::Base.connection.current_database } }
7
7
 
8
8
  describe "#init" do
9
9
  it "should process model exclusions" do
@@ -31,4 +31,4 @@ shared_examples_for "a connection based apartment adapter" do
31
31
  }.to raise_error(Apartment::DatabaseNotFound)
32
32
  end
33
33
  end
34
- end
34
+ end
@@ -14,8 +14,8 @@ 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
- database_names.should include(db1)
18
- database_names.should include(db2)
17
+ tenant_names.should include(db1)
18
+ tenant_names.should include(db2)
19
19
  end
20
20
 
21
21
  it "should load schema.rb to new schema" do
@@ -31,11 +31,11 @@ shared_examples_for "a generic apartment adapter" do
31
31
 
32
32
  subject.create(db2) do
33
33
  @count = User.count
34
- subject.current_database.should == db2
34
+ subject.current_tenant.should == db2
35
35
  User.create
36
36
  end
37
37
 
38
- subject.current_database.should_not == db2
38
+ subject.current_tenant.should_not == db2
39
39
 
40
40
  subject.process(db2){ User.count.should == @count + 1 }
41
41
  end
@@ -44,25 +44,25 @@ shared_examples_for "a generic apartment adapter" do
44
44
  describe "#drop" do
45
45
  it "should remove the db" do
46
46
  subject.drop db1
47
- database_names.should_not include(db1)
47
+ tenant_names.should_not include(db1)
48
48
  end
49
49
  end
50
50
 
51
51
  describe "#process" do
52
52
  it "should connect" do
53
53
  subject.process(db1) do
54
- subject.current_database.should == db1
54
+ subject.current_tenant.should == db1
55
55
  end
56
56
  end
57
57
 
58
58
  it "should reset" do
59
59
  subject.process(db1)
60
- subject.current_database.should == default_database
60
+ subject.current_tenant.should == default_tenant
61
61
  end
62
62
 
63
- # We're often finding when using Apartment in tests, the `current_database` (ie the previously connect to db)
63
+ # We're often finding when using Apartment in tests, the `current_tenant` (ie the previously connect to db)
64
64
  # gets dropped, but process will try to return to that db in a test. We should just reset if it doesn't exist
65
- it "should not throw exception if current_database is no longer accessible" do
65
+ it "should not throw exception if current_tenant is no longer accessible" do
66
66
  subject.switch(db2)
67
67
 
68
68
  expect {
@@ -75,19 +75,19 @@ shared_examples_for "a generic apartment adapter" do
75
75
  it "should reset connection" do
76
76
  subject.switch(db1)
77
77
  subject.reset
78
- subject.current_database.should == default_database
78
+ subject.current_tenant.should == default_tenant
79
79
  end
80
80
  end
81
81
 
82
82
  describe "#switch" do
83
83
  it "should connect to new db" do
84
84
  subject.switch(db1)
85
- subject.current_database.should == db1
85
+ subject.current_tenant.should == db1
86
86
  end
87
87
 
88
88
  it "should reset connection if database is nil" do
89
89
  subject.switch
90
- subject.current_database.should == default_database
90
+ subject.current_tenant.should == default_tenant
91
91
  end
92
92
 
93
93
  it "should raise an error if database is invalid" do
@@ -97,11 +97,11 @@ shared_examples_for "a generic apartment adapter" do
97
97
  end
98
98
  end
99
99
 
100
- describe "#current_database" do
100
+ describe "#current_tenant" do
101
101
  it "should return the current db name" do
102
102
  subject.switch(db1)
103
- subject.current_database.should == db1
103
+ subject.current_tenant.should == db1
104
104
  subject.current.should == db1
105
105
  end
106
106
  end
107
- end
107
+ end
@@ -5,7 +5,7 @@ shared_examples_for "a schema based apartment adapter" do
5
5
 
6
6
  let(:schema1){ db1 }
7
7
  let(:schema2){ db2 }
8
- let(:public_schema){ default_database }
8
+ let(:public_schema){ default_tenant }
9
9
 
10
10
  describe "#init" do
11
11
 
@@ -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
- database_names.should include(db.to_s)
79
+ tenant_names.should 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
- database_names.should_not include(db.to_s)
102
+ tenant_names.should_not include(db.to_s)
103
103
  end
104
104
 
105
105
  after { subject.drop(db) rescue nil }
@@ -213,17 +213,17 @@ shared_examples_for "a schema based apartment adapter" do
213
213
  end
214
214
  end
215
215
 
216
- describe "#current_database" do
216
+ describe "#current_tenant" do
217
217
  it "should return the current schema name" do
218
218
  subject.switch(schema1)
219
- subject.current_database.should == schema1
219
+ subject.current_tenant.should == schema1
220
220
  subject.current.should == schema1
221
221
  end
222
222
 
223
223
  context "persistent_schemas", :persistent_schemas => true do
224
224
  it "should exlude persistent_schemas" do
225
225
  subject.switch(schema1)
226
- subject.current_database.should == schema1
226
+ subject.current_tenant.should == schema1
227
227
  subject.current.should == schema1
228
228
  end
229
229
  end
@@ -19,7 +19,7 @@ describe "apartment rake tasks", database: :postgresql do
19
19
  Apartment.configure do |config|
20
20
  config.use_schemas = true
21
21
  config.excluded_models = ["Company"]
22
- config.database_names = lambda{ Company.pluck(:database) }
22
+ config.tenant_names = lambda{ Company.pluck(:database) }
23
23
  end
24
24
  Apartment::Database.reload!(config)
25
25
 
@@ -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+1).times
52
+ ActiveRecord::Migrator.should_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+1).times
60
+ ActiveRecord::Migrator.should_receive(:rollback).exactly(company_count).times
61
61
 
62
62
  @rake['apartment:rollback'].invoke
63
63
  end
@@ -71,4 +71,4 @@ describe "apartment rake tasks", database: :postgresql do
71
71
  end
72
72
  end
73
73
  end
74
- end
74
+ end
@@ -6,7 +6,7 @@ describe 'query caching' do
6
6
  before do
7
7
  Apartment.configure do |config|
8
8
  config.excluded_models = ["Company"]
9
- config.database_names = lambda{ Company.pluck(:database) }
9
+ config.tenant_names = lambda{ Company.pluck(:database) }
10
10
  config.use_schemas = true
11
11
  end
12
12
 
@@ -38,4 +38,4 @@ describe 'query caching' do
38
38
  Apartment::Database.switch db_names.last
39
39
  User.find_by_name(db_names.first).should be_nil
40
40
  end
41
- end
41
+ end
@@ -7,11 +7,9 @@ module Apartment
7
7
  #
8
8
  #
9
9
  module AdapterRequirements
10
-
11
10
  extend ActiveSupport::Concern
12
11
 
13
12
  included do
14
-
15
13
  before do
16
14
  subject.create(db1)
17
15
  subject.create(db2)
@@ -27,12 +25,11 @@ module Apartment
27
25
  end
28
26
  end
29
27
 
30
- %w{subject database_names default_database}.each do |method|
28
+ %w{subject tenant_names default_tenant}.each do |method|
31
29
  define_method method do
32
30
  raise "You must define a `#{method}` method in your host group"
33
31
  end unless defined?(method)
34
32
  end
35
-
36
33
  end
37
34
  end
38
- end
35
+ end
@@ -30,11 +30,11 @@ describe "apartment rake tasks" do
30
30
 
31
31
  context 'database migration' do
32
32
 
33
- let(:database_names){ 3.times.map{ Apartment::Test.next_db } }
34
- let(:db_count){ database_names.length }
33
+ let(:tenant_names){ 3.times.map{ Apartment::Test.next_db } }
34
+ let(:tenant_count){ tenant_names.length }
35
35
 
36
36
  before do
37
- Apartment.stub(:database_names).and_return database_names
37
+ Apartment.stub(:tenant_names).and_return tenant_names
38
38
  end
39
39
 
40
40
  describe "apartment:migrate" do
@@ -43,7 +43,7 @@ describe "apartment rake tasks" do
43
43
  end
44
44
 
45
45
  it "should migrate public and all multi-tenant dbs" do
46
- Apartment::Migrator.should_receive(:migrate).exactly(db_count).times
46
+ Apartment::Migrator.should_receive(:migrate).exactly(tenant_count).times
47
47
  @rake['apartment:migrate'].invoke
48
48
  end
49
49
  end
@@ -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(db_count).times
72
+ Apartment::Migrator.should_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
@@ -96,23 +96,22 @@ 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(db_count).times
99
+ Apartment::Migrator.should_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
103
103
  end
104
104
 
105
105
  describe "apartment:rollback" do
106
-
107
106
  let(:step){ '3' }
108
107
 
109
108
  it "should rollback dbs" do
110
- Apartment::Migrator.should_receive(:rollback).exactly(db_count).times
109
+ Apartment::Migrator.should_receive(:rollback).exactly(tenant_count).times
111
110
  @rake['apartment:rollback'].invoke
112
111
  end
113
112
 
114
113
  it "should rollback dbs STEP amt" do
115
- Apartment::Migrator.should_receive(:rollback).with(anything, step.to_i).exactly(db_count).times
114
+ Apartment::Migrator.should_receive(:rollback).with(anything, step.to_i).exactly(tenant_count).times
116
115
  ENV['STEP'] = step
117
116
  @rake['apartment:rollback'].invoke
118
117
  end
@@ -36,26 +36,33 @@ describe Apartment do
36
36
  Apartment.seed_after_create.should be_true
37
37
  end
38
38
 
39
+ it "should set tld_length" do
40
+ Apartment.configure do |config|
41
+ config.tld_length = 2
42
+ end
43
+ Apartment.tld_length.should == 2
44
+ end
45
+
39
46
  context "databases" do
40
47
  it "should return object if it doesnt respond_to call" do
41
- database_names = ['users', 'companies']
48
+ tenant_names = ['users', 'companies']
42
49
 
43
50
  Apartment.configure do |config|
44
51
  config.excluded_models = []
45
- config.database_names = database_names
52
+ config.tenant_names = tenant_names
46
53
  end
47
- Apartment.database_names.should == database_names
54
+ Apartment.tenant_names.should == tenant_names
48
55
  end
49
56
 
50
57
  it "should invoke the proc if appropriate" do
51
- database_names = lambda{ ['users', 'users'] }
52
- database_names.should_receive(:call)
58
+ tenant_names = lambda{ ['users', 'users'] }
59
+ tenant_names.should_receive(:call)
53
60
 
54
61
  Apartment.configure do |config|
55
62
  config.excluded_models = []
56
- config.database_names = database_names
63
+ config.tenant_names = tenant_names
57
64
  end
58
- Apartment.database_names
65
+ Apartment.tenant_names
59
66
  end
60
67
 
61
68
  it "should return the invoked proc if appropriate" do
@@ -63,12 +70,12 @@ describe Apartment do
63
70
 
64
71
  Apartment.configure do |config|
65
72
  config.excluded_models = []
66
- config.database_names = dbs
73
+ config.tenant_names = dbs
67
74
  end
68
75
 
69
- Apartment.database_names.should == Company.all
76
+ Apartment.tenant_names.should == Company.all
70
77
  end
71
78
  end
72
79
 
73
80
  end
74
- end
81
+ end