apartment 0.23.2 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.
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