apartment 0.15.0 → 0.16.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.
- data/.pryrc +3 -0
- data/.travis.yml +5 -0
- data/HISTORY.md +8 -0
- data/README.md +66 -14
- data/Rakefile +11 -10
- data/apartment.gemspec +6 -5
- data/lib/apartment.rb +21 -3
- data/lib/apartment/adapters/{mysql_adapter.rb → mysql2_adapter.rb} +7 -7
- data/lib/apartment/adapters/postgresql_adapter.rb +26 -15
- data/lib/apartment/database.rb +3 -0
- data/lib/apartment/elevators/domain.rb +18 -0
- data/lib/apartment/elevators/generic.rb +27 -0
- data/lib/apartment/elevators/subdomain.rb +5 -19
- data/lib/apartment/version.rb +1 -1
- data/spec/adapters/{mysql_adapter_spec.rb → mysql2_adapter_spec.rb} +7 -7
- data/spec/adapters/postgresql_adapter_spec.rb +4 -4
- data/spec/config/database.yml +2 -1
- data/spec/database_spec.rb +49 -26
- data/spec/dummy/config/application.rb +3 -0
- data/spec/examples/db_adapter_examples.rb +8 -8
- data/spec/examples/elevator_examples.rb +31 -0
- data/spec/examples/generic_adapter_examples.rb +10 -10
- data/spec/examples/schema_adapter_examples.rb +125 -38
- data/spec/integration/delayed_job_integration_spec.rb +1 -1
- data/spec/integration/middleware/domain_elevator_spec.rb +9 -0
- data/spec/integration/middleware/generic_elevator_spec.rb +10 -0
- data/spec/integration/middleware/subdomain_elevator_spec.rb +6 -49
- data/spec/spec_helper.rb +5 -2
- data/spec/support/apartment_helpers.rb +13 -10
- data/spec/support/contexts.rb +54 -0
- data/spec/support/requirements.rb +4 -4
- data/spec/unit/config_spec.rb +0 -4
- data/spec/unit/middleware/domain_elevator_spec.rb +26 -0
- data/spec/unit/middleware/subdomain_elevator_spec.rb +7 -7
- metadata +119 -108
@@ -0,0 +1,27 @@
|
|
1
|
+
module Apartment
|
2
|
+
module Elevators
|
3
|
+
# Provides a rack based db switching solution based on request
|
4
|
+
#
|
5
|
+
class Generic
|
6
|
+
|
7
|
+
def initialize(app, processor = nil)
|
8
|
+
@app = app
|
9
|
+
@processor = processor || method(:parse_database_name)
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
request = ActionDispatch::Request.new(env)
|
14
|
+
|
15
|
+
database = @processor.call(request)
|
16
|
+
|
17
|
+
Apartment::Database.switch database if database
|
18
|
+
|
19
|
+
@app.call(env)
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_database_name(request)
|
23
|
+
raise "Override"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,27 +1,13 @@
|
|
1
1
|
module Apartment
|
2
2
|
module Elevators
|
3
|
-
#
|
4
|
-
#
|
5
|
-
|
3
|
+
# Provides a rack based db switching solution based on subdomains
|
4
|
+
# Assumes that database name should match subdomain
|
5
|
+
#
|
6
|
+
class Subdomain < Generic
|
6
7
|
|
7
|
-
def
|
8
|
-
@app = app
|
9
|
-
end
|
10
|
-
|
11
|
-
def call(env)
|
12
|
-
request = ActionDispatch::Request.new(env)
|
13
|
-
|
14
|
-
database = subdomain(request)
|
15
|
-
|
16
|
-
Apartment::Database.switch database if database
|
17
|
-
|
18
|
-
@app.call(env)
|
19
|
-
end
|
20
|
-
|
21
|
-
def subdomain(request)
|
8
|
+
def parse_database_name(request)
|
22
9
|
request.subdomain.present? && request.subdomain || nil
|
23
10
|
end
|
24
|
-
|
25
11
|
end
|
26
12
|
end
|
27
13
|
end
|
data/lib/apartment/version.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'apartment/adapters/
|
2
|
+
require 'apartment/adapters/mysql2_adapter'
|
3
|
+
|
4
|
+
describe Apartment::Adapters::Mysql2Adapter do
|
3
5
|
|
4
|
-
describe Apartment::Adapters::MysqlAdapter do
|
5
|
-
|
6
6
|
let(:config){ Apartment::Test.config['connections']['mysql'] }
|
7
7
|
subject{ Apartment::Database.mysql2_adapter config.symbolize_keys }
|
8
|
-
|
8
|
+
|
9
9
|
def database_names
|
10
10
|
ActiveRecord::Base.connection.execute("SELECT schema_name FROM information_schema.schemata").collect{|row| row[0]}
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
let(:default_database){ subject.process{ ActiveRecord::Base.connection.current_database } }
|
14
|
-
|
14
|
+
|
15
15
|
it_should_behave_like "a generic apartment adapter"
|
16
16
|
it_should_behave_like "a db based apartment adapter"
|
17
|
-
end
|
17
|
+
end
|
@@ -14,22 +14,22 @@ describe Apartment::Adapters::PostgresqlAdapter do
|
|
14
14
|
def database_names
|
15
15
|
ActiveRecord::Base.connection.execute("SELECT nspname FROM pg_namespace;").collect{|row| row['nspname']}
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
let(:default_database){ subject.process{ ActiveRecord::Base.connection.schema_search_path } }
|
19
19
|
|
20
20
|
it_should_behave_like "a generic apartment adapter"
|
21
21
|
it_should_behave_like "a schema based apartment adapter"
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
context "using databases" do
|
25
25
|
|
26
|
-
before{ Apartment.use_postgres_schemas = false }
|
26
|
+
before{ Apartment.use_postgres_schemas = false }
|
27
27
|
|
28
28
|
# Not sure why, but somehow using let(:database_names) memoizes for the whole example group, not just each test
|
29
29
|
def database_names
|
30
30
|
connection.execute("select datname from pg_database;").collect{|row| row['datname']}
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
let(:default_database){ subject.process{ ActiveRecord::Base.connection.current_database } }
|
34
34
|
|
35
35
|
it_should_behave_like "a generic apartment adapter"
|
data/spec/config/database.yml
CHANGED
data/spec/database_spec.rb
CHANGED
@@ -1,44 +1,67 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Apartment::Database do
|
4
|
-
|
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 }
|
8
|
+
|
9
|
+
before do
|
10
|
+
ActiveRecord::Base.establish_connection config
|
11
|
+
Apartment::Test.load_schema # load the Rails schema in the public db schema
|
12
|
+
subject.stub(:config).and_return config # Use postgresql database config for this test
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#adapter" do
|
16
|
+
before do
|
17
|
+
subject.reload!
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should load mysql adapter" do
|
21
|
+
subject.adapter
|
22
|
+
Apartment::Adapters::Mysql2Adapter.should be_a(Class)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
5
28
|
context "using postgresql" do
|
6
|
-
|
29
|
+
|
7
30
|
# See apartment.yml file in dummy app config
|
8
|
-
|
31
|
+
|
9
32
|
let(:config){ Apartment::Test.config['connections']['postgresql'].symbolize_keys }
|
10
33
|
let(:database){ Apartment::Test.next_db }
|
11
34
|
let(:database2){ Apartment::Test.next_db }
|
12
|
-
|
35
|
+
|
13
36
|
before do
|
14
37
|
Apartment.use_postgres_schemas = true
|
15
38
|
ActiveRecord::Base.establish_connection config
|
16
39
|
Apartment::Test.load_schema # load the Rails schema in the public db schema
|
17
40
|
subject.stub(:config).and_return config # Use postgresql database config for this test
|
18
41
|
end
|
19
|
-
|
42
|
+
|
20
43
|
describe "#adapter" do
|
21
44
|
before do
|
22
45
|
subject.reload!
|
23
46
|
end
|
24
|
-
|
47
|
+
|
25
48
|
it "should load postgresql adapter" do
|
26
49
|
subject.adapter
|
27
50
|
Apartment::Adapters::PostgresqlAdapter.should be_a(Class)
|
28
51
|
end
|
29
|
-
|
52
|
+
|
30
53
|
it "should raise exception with invalid adapter specified" do
|
31
54
|
subject.stub(:config).and_return config.merge(:adapter => 'unkown')
|
32
|
-
|
55
|
+
|
33
56
|
expect {
|
34
57
|
Apartment::Database.adapter
|
35
58
|
}.to raise_error
|
36
59
|
end
|
37
|
-
|
60
|
+
|
38
61
|
end
|
39
|
-
|
62
|
+
|
40
63
|
context "with schemas" do
|
41
|
-
|
64
|
+
|
42
65
|
before do
|
43
66
|
Apartment.configure do |config|
|
44
67
|
config.excluded_models = []
|
@@ -47,25 +70,25 @@ describe Apartment::Database do
|
|
47
70
|
end
|
48
71
|
subject.create database
|
49
72
|
end
|
50
|
-
|
73
|
+
|
51
74
|
after{ subject.drop database }
|
52
|
-
|
75
|
+
|
53
76
|
describe "#create" do
|
54
77
|
it "should seed data" do
|
55
78
|
subject.switch database
|
56
79
|
User.count.should be > 0
|
57
80
|
end
|
58
81
|
end
|
59
|
-
|
82
|
+
|
60
83
|
describe "#switch" do
|
61
|
-
|
84
|
+
|
62
85
|
let(:x){ rand(3) }
|
63
|
-
|
86
|
+
|
64
87
|
context "creating models" do
|
65
|
-
|
88
|
+
|
66
89
|
before{ subject.create database2 }
|
67
90
|
after{ subject.drop database2 }
|
68
|
-
|
91
|
+
|
69
92
|
it "should create a model instance in the current schema" do
|
70
93
|
subject.switch database2
|
71
94
|
db2_count = User.count + x.times{ User.create }
|
@@ -80,20 +103,20 @@ describe Apartment::Database do
|
|
80
103
|
User.count.should == db_count
|
81
104
|
end
|
82
105
|
end
|
83
|
-
|
106
|
+
|
84
107
|
context "with excluded models" do
|
85
|
-
|
108
|
+
|
86
109
|
before do
|
87
110
|
Apartment.configure do |config|
|
88
111
|
config.excluded_models = ["Company"]
|
89
112
|
end
|
90
113
|
subject.init
|
91
114
|
end
|
92
|
-
|
115
|
+
|
93
116
|
it "should create excluded models in public schema" do
|
94
117
|
subject.reset # ensure we're on public schema
|
95
118
|
count = Company.count + x.times{ Company.create }
|
96
|
-
|
119
|
+
|
97
120
|
subject.switch database
|
98
121
|
x.times{ Company.create }
|
99
122
|
Company.count.should == count + x
|
@@ -101,10 +124,10 @@ describe Apartment::Database do
|
|
101
124
|
Company.count.should == count + x
|
102
125
|
end
|
103
126
|
end
|
104
|
-
|
127
|
+
|
105
128
|
end
|
106
|
-
|
129
|
+
|
107
130
|
end
|
108
|
-
|
131
|
+
|
109
132
|
end
|
110
|
-
end
|
133
|
+
end
|
@@ -16,6 +16,9 @@ module Dummy
|
|
16
16
|
# -- all .rb files in that directory are automatically loaded.
|
17
17
|
|
18
18
|
config.middleware.use 'Apartment::Elevators::Subdomain'
|
19
|
+
config.middleware.use 'Apartment::Elevators::Domain'
|
20
|
+
# Our test for this middleware is using a query_string couldn't think of a better way to differentiate it from the other middleware
|
21
|
+
config.middleware.use 'Apartment::Elevators::Generic', Proc.new { |request| request.query_string.split('=').last if request.query_string.present? }
|
19
22
|
|
20
23
|
# Custom directories with classes and modules you want to be autoloadable.
|
21
24
|
config.autoload_paths += %W(#{config.root}/lib)
|
@@ -2,30 +2,30 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
shared_examples_for "a db based apartment adapter" do
|
4
4
|
include Apartment::Spec::AdapterRequirements
|
5
|
-
|
5
|
+
|
6
6
|
let(:default_database){ subject.process{ ActiveRecord::Base.connection.current_database } }
|
7
|
-
|
7
|
+
|
8
8
|
describe "#init" do
|
9
|
-
|
9
|
+
|
10
10
|
it "should process model exclusions" do
|
11
11
|
Apartment.configure do |config|
|
12
12
|
config.excluded_models = ["Company"]
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
Apartment::Database.init
|
16
|
-
|
16
|
+
|
17
17
|
Company.connection.object_id.should_not == ActiveRecord::Base.connection.object_id
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
describe "#drop" do
|
22
22
|
it "should raise an error for unknown database" do
|
23
23
|
expect {
|
24
24
|
subject.drop 'unknown_database'
|
25
25
|
}.to raise_error(Apartment::DatabaseNotFound)
|
26
26
|
end
|
27
|
-
end
|
28
|
-
|
27
|
+
end
|
28
|
+
|
29
29
|
describe "#switch" do
|
30
30
|
it "should raise an error if database is invalid" do
|
31
31
|
expect {
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for "an apartment elevator" do
|
4
|
+
|
5
|
+
context "single request" do
|
6
|
+
it "should switch the db" do
|
7
|
+
ActiveRecord::Base.connection.schema_search_path.should_not == database1
|
8
|
+
|
9
|
+
visit(domain1)
|
10
|
+
ActiveRecord::Base.connection.schema_search_path.should == database1
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "simultaneous requests" do
|
15
|
+
|
16
|
+
let!(:c1_user_count) { api.process(database1){ (2 + rand(2)).times{ User.create } } }
|
17
|
+
let!(:c2_user_count) { api.process(database2){ (c1_user_count + 2).times{ User.create } } }
|
18
|
+
|
19
|
+
it "should fetch the correct user count for each session based on the elevator processor" do
|
20
|
+
visit(domain1)
|
21
|
+
|
22
|
+
in_new_session do |session|
|
23
|
+
session.visit(domain2)
|
24
|
+
User.count.should == c2_user_count
|
25
|
+
end
|
26
|
+
|
27
|
+
visit(domain1)
|
28
|
+
User.count.should == c1_user_count
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -2,9 +2,9 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
shared_examples_for "a generic apartment adapter" do
|
4
4
|
include Apartment::Spec::AdapterRequirements
|
5
|
-
|
5
|
+
|
6
6
|
before{ Apartment.prepend_environment = false }
|
7
|
-
|
7
|
+
|
8
8
|
#
|
9
9
|
# Creates happen already in our before_filter
|
10
10
|
#
|
@@ -20,7 +20,7 @@ shared_examples_for "a generic apartment adapter" do
|
|
20
20
|
connection.tables.should include('companies')
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
it "should yield to block if passed and reset" do
|
25
25
|
subject.drop(db2) # so we don't get errors on creation
|
26
26
|
|
@@ -31,20 +31,20 @@ shared_examples_for "a generic apartment adapter" do
|
|
31
31
|
subject.current_database.should == db2
|
32
32
|
User.create
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
subject.current_database.should_not == db2
|
36
36
|
|
37
37
|
subject.process(db2){ User.count.should == @count + 1 }
|
38
|
-
end
|
38
|
+
end
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
describe "#drop" do
|
42
42
|
it "should remove the db" do
|
43
43
|
subject.drop db1
|
44
44
|
database_names.should_not include(db1)
|
45
|
-
end
|
45
|
+
end
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
describe "#process" do
|
49
49
|
it "should connect" do
|
50
50
|
subject.process(db1) do
|
@@ -67,7 +67,7 @@ shared_examples_for "a generic apartment adapter" do
|
|
67
67
|
}.to_not raise_error
|
68
68
|
end
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
describe "#reset" do
|
72
72
|
it "should reset connection" do
|
73
73
|
subject.switch(db1)
|
@@ -85,7 +85,7 @@ shared_examples_for "a generic apartment adapter" do
|
|
85
85
|
it "should reset connection if database is nil" do
|
86
86
|
subject.switch
|
87
87
|
subject.current_database.should == default_database
|
88
|
-
end
|
88
|
+
end
|
89
89
|
end
|
90
90
|
|
91
91
|
describe "#current_database" do
|
@@ -2,22 +2,33 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
shared_examples_for "a schema based apartment adapter" do
|
4
4
|
include Apartment::Spec::AdapterRequirements
|
5
|
-
|
5
|
+
|
6
6
|
let(:schema1){ db1 }
|
7
7
|
let(:schema2){ db2 }
|
8
8
|
let(:public_schema){ default_database }
|
9
9
|
|
10
10
|
describe "#init" do
|
11
|
-
|
12
|
-
|
11
|
+
|
12
|
+
before do
|
13
13
|
Apartment.configure do |config|
|
14
14
|
config.excluded_models = ["Company"]
|
15
15
|
end
|
16
|
-
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should process model exclusions" do
|
17
19
|
Apartment::Database.init
|
18
|
-
|
20
|
+
|
19
21
|
Company.table_name.should == "public.companies"
|
20
22
|
end
|
23
|
+
|
24
|
+
context "with a default_schema", :default_schema => true do
|
25
|
+
|
26
|
+
it "should set the proper table_name on excluded_models" do
|
27
|
+
Apartment::Database.init
|
28
|
+
|
29
|
+
Company.table_name.should == "#{default_schema}.companies"
|
30
|
+
end
|
31
|
+
end
|
21
32
|
end
|
22
33
|
|
23
34
|
#
|
@@ -29,7 +40,7 @@ shared_examples_for "a schema based apartment adapter" do
|
|
29
40
|
connection.schema_search_path = schema1
|
30
41
|
connection.tables.should include('companies')
|
31
42
|
end
|
32
|
-
|
43
|
+
|
33
44
|
it "should yield to block if passed and reset" do
|
34
45
|
subject.drop(schema2) # so we don't get errors on creation
|
35
46
|
|
@@ -37,52 +48,61 @@ shared_examples_for "a schema based apartment adapter" do
|
|
37
48
|
|
38
49
|
subject.create(schema2) do
|
39
50
|
@count = User.count
|
40
|
-
connection.schema_search_path.should
|
51
|
+
connection.schema_search_path.should start_with schema2
|
41
52
|
User.create
|
42
53
|
end
|
43
|
-
|
44
|
-
connection.schema_search_path.should_not
|
54
|
+
|
55
|
+
connection.schema_search_path.should_not start_with schema2
|
45
56
|
|
46
57
|
subject.process(schema2){ User.count.should == @count + 1 }
|
47
58
|
end
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
59
|
+
|
60
|
+
context "numeric database names" do
|
61
|
+
let(:db){ 1234 }
|
62
|
+
it "should allow them" do
|
63
|
+
expect {
|
64
|
+
subject.create(db)
|
65
|
+
}.to_not raise_error
|
66
|
+
database_names.should include(db.to_s)
|
67
|
+
end
|
68
|
+
|
69
|
+
after{ subject.drop(db) }
|
56
70
|
end
|
57
|
-
|
71
|
+
|
58
72
|
end
|
59
|
-
|
73
|
+
|
60
74
|
describe "#drop" do
|
61
75
|
it "should raise an error for unknown database" do
|
62
76
|
expect {
|
63
77
|
subject.drop "unknown_database"
|
64
78
|
}.to raise_error(Apartment::SchemaNotFound)
|
65
79
|
end
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
80
|
+
|
81
|
+
context "numeric database names" do
|
82
|
+
let(:db){ 1234 }
|
83
|
+
|
84
|
+
it "should be able to drop them" do
|
85
|
+
subject.create(db)
|
86
|
+
expect {
|
87
|
+
subject.drop(db)
|
88
|
+
}.to_not raise_error
|
89
|
+
database_names.should_not include(db.to_s)
|
90
|
+
end
|
91
|
+
|
92
|
+
after { subject.drop(db) rescue nil }
|
73
93
|
end
|
74
94
|
end
|
75
95
|
|
76
96
|
describe "#process" do
|
77
97
|
it "should connect" do
|
78
98
|
subject.process(schema1) do
|
79
|
-
connection.schema_search_path.should
|
99
|
+
connection.schema_search_path.should start_with schema1
|
80
100
|
end
|
81
101
|
end
|
82
102
|
|
83
103
|
it "should reset" do
|
84
104
|
subject.process(schema1)
|
85
|
-
connection.schema_search_path.should
|
105
|
+
connection.schema_search_path.should start_with public_schema
|
86
106
|
end
|
87
107
|
end
|
88
108
|
|
@@ -90,33 +110,93 @@ shared_examples_for "a schema based apartment adapter" do
|
|
90
110
|
it "should reset connection" do
|
91
111
|
subject.switch(schema1)
|
92
112
|
subject.reset
|
93
|
-
connection.schema_search_path.should
|
113
|
+
connection.schema_search_path.should start_with public_schema
|
114
|
+
end
|
115
|
+
|
116
|
+
context "with default_schema", :default_schema => true do
|
117
|
+
it "should reset to the default schema" do
|
118
|
+
subject.switch(schema1)
|
119
|
+
subject.reset
|
120
|
+
connection.schema_search_path.should start_with default_schema
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "persistent_schemas", :persistent_schemas => true do
|
125
|
+
before do
|
126
|
+
subject.switch(schema1)
|
127
|
+
subject.reset
|
128
|
+
end
|
129
|
+
|
130
|
+
it "maintains the persistent schemas in the schema_search_path" do
|
131
|
+
connection.schema_search_path.should end_with persistent_schemas.join(', ')
|
132
|
+
end
|
133
|
+
|
134
|
+
context "with default_schema", :default_schema => true do
|
135
|
+
it "prioritizes the switched schema to front of schema_search_path" do
|
136
|
+
subject.reset # need to re-call this as the default_schema wasn't set at the time that the above reset ran
|
137
|
+
connection.schema_search_path.should start_with default_schema
|
138
|
+
end
|
139
|
+
end
|
94
140
|
end
|
95
141
|
end
|
96
142
|
|
97
143
|
describe "#switch" do
|
98
144
|
it "should connect to new schema" do
|
99
145
|
subject.switch(schema1)
|
100
|
-
connection.schema_search_path.should
|
146
|
+
connection.schema_search_path.should start_with schema1
|
101
147
|
end
|
102
148
|
|
103
149
|
it "should reset connection if database is nil" do
|
104
150
|
subject.switch
|
105
151
|
connection.schema_search_path.should == public_schema
|
106
152
|
end
|
107
|
-
|
153
|
+
|
108
154
|
it "should raise an error if schema is invalid" do
|
109
155
|
expect {
|
110
156
|
subject.switch 'unknown_schema'
|
111
157
|
}.to raise_error(Apartment::SchemaNotFound)
|
112
158
|
end
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
159
|
+
|
160
|
+
context "numeric databases" do
|
161
|
+
let(:db){ 1234 }
|
162
|
+
|
163
|
+
it "should connect to them" do
|
164
|
+
subject.create(db)
|
165
|
+
expect {
|
166
|
+
subject.switch(db)
|
167
|
+
}.to_not raise_error
|
168
|
+
|
169
|
+
connection.schema_search_path.should start_with db.to_s
|
170
|
+
end
|
171
|
+
|
172
|
+
after{ subject.drop(db) }
|
173
|
+
end
|
174
|
+
|
175
|
+
describe "with default_schema specified", :default_schema => true do
|
176
|
+
before do
|
177
|
+
subject.switch(schema1)
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should switch out the default schema rather than public" do
|
181
|
+
connection.schema_search_path.should_not include default_schema
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should still switch to the switched schema" do
|
185
|
+
connection.schema_search_path.should start_with schema1
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context "persistent_schemas", :persistent_schemas => true do
|
190
|
+
|
191
|
+
before{ subject.switch(schema1) }
|
192
|
+
|
193
|
+
it "maintains the persistent schemas in the schema_search_path" do
|
194
|
+
connection.schema_search_path.should end_with persistent_schemas.join(', ')
|
195
|
+
end
|
196
|
+
|
197
|
+
it "prioritizes the switched schema to front of schema_search_path" do
|
198
|
+
connection.schema_search_path.should start_with schema1
|
199
|
+
end
|
120
200
|
end
|
121
201
|
end
|
122
202
|
|
@@ -125,6 +205,13 @@ shared_examples_for "a schema based apartment adapter" do
|
|
125
205
|
subject.switch(schema1)
|
126
206
|
subject.current_database.should == schema1
|
127
207
|
end
|
208
|
+
|
209
|
+
context "persistent_schemas", :persistent_schemas => true do
|
210
|
+
it "should exlude persistent_schemas" do
|
211
|
+
subject.switch(schema1)
|
212
|
+
subject.current_database.should == schema1
|
213
|
+
end
|
214
|
+
end
|
128
215
|
end
|
129
216
|
|
130
217
|
end
|