apartment 0.21.1 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 633c827866f4356529e375c9fe6b1b2f8886dbf3
4
+ data.tar.gz: 8b568ba43bbc49eb726ecc439b314b9c19c73ff3
5
+ SHA512:
6
+ metadata.gz: 96084d067de04ce41892a639887c7ce2d248e556c1624879721f0bf4529348cf504f04c408f7f82a6cbb17366078d48b542bf75f5b569cd32f85b684ff380739
7
+ data.tar.gz: 1173968bbe02e081870bba50bbbab33775e16a6f42e213b34bb15b0a47929fe1d8dcc8ca83eca243669ded99a8dd9a52d1cf46e49d995fb62209b0f877d71336
@@ -0,0 +1 @@
1
+ apartment
@@ -0,0 +1 @@
1
+ ruby-2.0.0
@@ -3,5 +3,5 @@ rvm:
3
3
  - 1.9.2
4
4
  - 1.9.3
5
5
  - 2.0.0
6
- - jruby-19mode
6
+ - jruby-19mode-1.7.4
7
7
  bundler_args: --without local --verbose
data/HISTORY.md CHANGED
@@ -1,3 +1,14 @@
1
+ # 0.22.0
2
+ * June 9, 2013
3
+
4
+ - Numerous bug fixes:
5
+ - Mysql reset could connect to wrong database [eric88]
6
+ - Postgresql schema names weren't quoted properly [gdott9]
7
+ - Fixed error message on SchemaNotFound in `process`
8
+ - HostHash elevator allows mapping host based on hash contents [gdott9]
9
+ - Official Sidekiq support with the [apartment-sidekiq gem](https://github.com/influitive/apartment-sidekiq)
10
+
11
+
1
12
  # 0.21.1
2
13
  * May 31, 2013
3
14
 
data/README.md CHANGED
@@ -94,6 +94,18 @@ module My Application
94
94
  end
95
95
  ```
96
96
 
97
+ **Switch on full host using a hash**
98
+ To switch based on full host with a hash to find corresponding database name use the following:
99
+
100
+ ```ruby
101
+ # application.rb
102
+ module My Application
103
+ class Application < Rails::Application
104
+ config.middleware.use 'Apartment::Elevators::HostHash', {'example.com' => 'example_database'}
105
+ end
106
+ end
107
+ ```
108
+
97
109
  **Custom Elevator**
98
110
  A Generic Elevator exists that allows you to pass a `Proc` (or anything that responds to `call`) to the middleware. This Object will be passed in an `ActionDispatch::Request` object when called for you to do your magic. Apartment will use the return value of this proc to switch to the appropriate database. Use like so:
99
111
 
@@ -281,7 +293,7 @@ All jobs *must* stored in the global (public) namespace, so add it to the list o
281
293
  config.excluded_models = ["Delayed::Job"]
282
294
  ```
283
295
 
284
- ## Development
296
+ ## Contributing
285
297
 
286
298
  * In both `spec/dummy/config` and `spec/config`, you will see `database.yml.sample` files
287
299
  * Copy them into the same directory but with the name `database.yml`
@@ -290,6 +302,8 @@ config.excluded_models = ["Delayed::Job"]
290
302
  * Please issue pull requests to the `development` branch. All development happens here, master is used for releases
291
303
  * Ensure that your code is accompanied with tests. No code will be merged without tests
292
304
 
305
+ * If you're looking to help, check out the TODO file for some upcoming changes I'd like to implement in Apartment.
306
+
293
307
  ## License
294
308
 
295
309
  Apartment is released under the [MIT License](http://www.opensource.org/licenses/MIT).
data/TODO.md ADDED
@@ -0,0 +1,52 @@
1
+ # Apartment TODOs
2
+
3
+ ### Below is a list of tasks in the approximate order to be completed of for Apartment
4
+ ### Any help along the way is greatly appreciated (on any items, not particularly in order)
5
+
6
+ 1. Apartment was originally written (and TDD'd) with just Postgresql in mind. Different adapters were added at a later date.
7
+ As such, the test suite is a bit of a mess. There's no formal structure for fully integration testing all adapters to ensure
8
+ proper quality and prevent regressions.
9
+
10
+ There's also a test order dependency as some tests run assuming a db connection and if that test randomly ran before a previous
11
+ one that makes the connection, it would fail.
12
+
13
+ I'm proposing the first thing to be done is to write up a standard, high livel integration test case that can be applied to all adapters
14
+ and makes no assumptions about implementation. It should ensure that each adapter conforms to the Apartment Interface and CRUD's properly.
15
+ It would be nice if a user can 'register' an adapter such that it would automatically be tested (nice to have). Otherwise one could just use
16
+ a shared behaviour to run through all of this.
17
+
18
+ Then, I'd like to see all of the implementation specific tests just in their own test file for each adapter (ie the postgresql schema adapter
19
+ checks a lot of things with `schema_search_path`)
20
+
21
+ This should ensure that going forward nothing breaks, and we should *ideally* be able to randomize the test order
22
+
23
+ 2. `Apartment::Database` is the wrong abstraction. When dealing with a multi-tenanted system, users shouldn't thing about 'Databases', they should
24
+ think about Tenants. I proprose that we deprecate the `Apartment::Database` constant in favour of `Apartment::Tenant` for a nicer abstraction. See
25
+ http://myronmars.to/n/dev-blog/2011/09/deprecating-constants-and-classes-in-ruby for ideas on how to achieve this.
26
+
27
+ 3. `Delayed::Job` has proven to be an absolute P.I.T.A. It's YAML hacks are beyond reproach and require further hacks in order to work properly.
28
+ I want to completely remove the Delayed::Job dependency from Apartment and make an `apartment-delayed-job` gem that can be worked on independently
29
+ (and hopefully eventually deprecated). To this end, I've started an `apartment-sidekiq` gem and would love to see an `apartment-resque` gem to deal
30
+ with those background workers from a multi-tenant perspective also.
31
+
32
+ 4. Apartment::Database.process should be deprecated in favour of just passing an optional block to `switch`
33
+
34
+ 5. Migrations right now can be a bit of a pain. Apartment currently migrates a single tenant completely up to date, then goes onto the next. If one of these
35
+ migrations fails on a tenant, the previous one does NOT get reverted and leaves you in an awkward state. Ideally we'd want to wrap all of the migrations in
36
+ a transaction so if one fails, the whole thing reverts. Once we can ensure an all-or-nothing approach to migrations, we can optimize the migration strategy
37
+ to not even iterate over the tenants if there are no migrations to run on public. I also thought id would be nice to provide an optional file to require in one's
38
+ Rakefile such that it would override `db:migrate` to do `apartment:migrate`. That way people don't have to remember to use a different task and there's no confusion.
39
+
40
+ 6. Apartment has be come one of the most popular/robust Multi-tenant gems for Rails, but it still doesn't work for everyone's use case. It's fairly limited
41
+ in implementation to either schema based (ie postgresql schemas) or connection based. I'd like to abstract out these implementation details such that one
42
+ could write a pluggable strategy for Apartment and choose it based on a config selection (something like `config.strategy = :schema`). The next implementation
43
+ I'd like to see is a scoped based approach that uses a `tenant_id` scoping on all records for multi-tenancy. This is probably the most popular multi-tenant approach
44
+ and is db independent and really the simplest mechanism for a type of multi-tenancy.
45
+
46
+ 7. Right now excluded tables still live in all tenanted environments. This is basically because it doesn't matter if they're there, we always query from the public.
47
+ It's a bit of an annoyance though and confuses lots of people. I'd love to see only tenanted tables in the tenants and only excluded tables in the public tenant.
48
+ This will be hard because Rails uses public to generate schema.rb. One idea is to have an `excluded` schema that holds all the excluded models and the public can
49
+ maintain everything.
50
+
51
+ 8. This one is pretty lofty, but I'd also like to abstract out the fact that Apartment uses ActiveRecord. With the new DataMapper coming out soon and other popular
52
+ DBMS's (ie. mongo, couch etc...), it'd be nice if Apartment could be the de-facto interface for multi-tenancy on these systems.
@@ -80,6 +80,7 @@ module Apartment
80
80
  autoload :Subdomain, 'apartment/elevators/subdomain'
81
81
  autoload :FirstSubdomain, 'apartment/elevators/first_subdomain'
82
82
  autoload :Domain, 'apartment/elevators/domain'
83
+ autoload :HostHash, 'apartment/elevators/host_hash'
83
84
  end
84
85
 
85
86
  module Delayed
@@ -41,7 +41,7 @@ module Apartment
41
41
  # Reset current_database to the default_database
42
42
  #
43
43
  def reset
44
- connect_to_new(default_database)
44
+ Apartment.connection.execute "use #{default_database}"
45
45
  end
46
46
 
47
47
  # Set the table_name to always use the default database for excluded models
@@ -57,7 +57,7 @@ module Apartment
57
57
  def connect_to_new(database)
58
58
  return reset if database.nil?
59
59
 
60
- Apartment.connection.execute "use #{database}"
60
+ Apartment.connection.execute "use #{environmentify(database)}"
61
61
 
62
62
  rescue ActiveRecord::StatementInvalid
63
63
  Apartment::Database.reset
@@ -79,7 +79,7 @@ module Apartment
79
79
  Apartment.connection.schema_search_path = full_search_path
80
80
 
81
81
  rescue *rescuable_exceptions
82
- raise SchemaNotFound, "One of the following schema(s) is invalid: #{full_search_path}"
82
+ raise SchemaNotFound, "One of the following schema(s) is invalid: #{database}, #{full_search_path}"
83
83
  end
84
84
 
85
85
  # Create the new schema
@@ -96,8 +96,8 @@ module Apartment
96
96
  # Generate the final search path to set including persistent_schemas
97
97
  #
98
98
  def full_search_path
99
- persistent_schemas = Apartment.persistent_schemas.join(', ')
100
- @current_database.to_s + (persistent_schemas.empty? ? "" : ", #{persistent_schemas}")
99
+ persistent_schemas = Apartment.persistent_schemas.map { |schema| %{"#{schema}"} }.join(', ')
100
+ %{"#{@current_database.to_s}"} + (persistent_schemas.empty? ? "" : ", #{persistent_schemas}")
101
101
  end
102
102
  end
103
103
  end
@@ -11,7 +11,7 @@ module Apartment
11
11
  def parse_database_name(request)
12
12
  return nil if request.host.blank?
13
13
 
14
- request.host.match(/(www.)?(?<sld>[^.]*)/)["sld"]
14
+ request.host.match(/(www\.)?(?<sld>[^.]*)/)["sld"]
15
15
  end
16
16
  end
17
17
  end
@@ -0,0 +1,20 @@
1
+ module Apartment
2
+ module Elevators
3
+ # Provides a rack based db switching solution based on hosts
4
+ # Uses a hash to find the corresponding database name for the host
5
+ #
6
+ class HostHash < Generic
7
+ def initialize(app, hash = {}, processor = nil)
8
+ super app, processor
9
+ @hash = hash
10
+ end
11
+
12
+ def parse_database_name(request)
13
+ raise DatabaseNotFound,
14
+ "Cannot find database for host #{request.host}" unless @hash.has_key?(request.host)
15
+
16
+ @hash[request.host]
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  module Apartment
2
- VERSION = "0.21.1"
2
+ VERSION = "0.22.0"
3
3
  end
@@ -1,21 +1,41 @@
1
1
  apartment_namespace = namespace :apartment do
2
2
 
3
+ desc "Create all multi-tenant databases"
4
+ task :create => 'db:migrate' do
5
+ database_names.each do |db|
6
+ begin
7
+ puts("Creating #{db} database")
8
+ quietly { Apartment::Database.create(db) }
9
+ rescue Apartment::DatabaseExists, Apartment::SchemaExists => e
10
+ puts e.message
11
+ end
12
+ end
13
+ end
14
+
3
15
  desc "Migrate all multi-tenant databases"
4
16
  task :migrate => 'db:migrate' do
5
17
 
6
- Apartment.database_names.each do |db|
7
- puts("Migrating #{db} database")
8
- Apartment::Migrator.migrate db
18
+ database_names.each do |db|
19
+ begin
20
+ puts("Migrating #{db} database")
21
+ Apartment::Migrator.migrate db
22
+ rescue Apartment::DatabaseNotFound, Apartment::SchemaNotFound => e
23
+ puts e.message
24
+ end
9
25
  end
10
26
  end
11
27
 
12
28
  desc "Seed all multi-tenant databases"
13
29
  task :seed => 'db:seed' do
14
30
 
15
- Apartment.database_names.each do |db|
16
- puts("Seeding #{db} database")
17
- Apartment::Database.process(db) do
18
- Apartment::Database.seed
31
+ database_names.each do |db|
32
+ begin
33
+ puts("Seeding #{db} database")
34
+ Apartment::Database.process(db) do
35
+ Apartment::Database.seed
36
+ end
37
+ rescue Apartment::DatabaseNotFound, Apartment::SchemaNotFound => e
38
+ puts e.message
19
39
  end
20
40
  end
21
41
  end
@@ -24,9 +44,13 @@ apartment_namespace = namespace :apartment do
24
44
  task :rollback => 'db:rollback' do
25
45
  step = ENV['STEP'] ? ENV['STEP'].to_i : 1
26
46
 
27
- Apartment.database_names.each do |db|
28
- puts("Rolling back #{db} database")
29
- Apartment::Migrator.rollback db, step
47
+ database_names.each do |db|
48
+ begin
49
+ puts("Rolling back #{db} database")
50
+ Apartment::Migrator.rollback db, step
51
+ rescue Apartment::DatabaseNotFound, Apartment::SchemaNotFound => e
52
+ puts e.message
53
+ end
30
54
  end
31
55
  end
32
56
 
@@ -37,9 +61,13 @@ apartment_namespace = namespace :apartment do
37
61
  version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
38
62
  raise 'VERSION is required' unless version
39
63
 
40
- Apartment.database_names.each do |db|
41
- puts("Migrating #{db} database up")
42
- Apartment::Migrator.run :up, db, version
64
+ database_names.each do |db|
65
+ begin
66
+ puts("Migrating #{db} database up")
67
+ Apartment::Migrator.run :up, db, version
68
+ rescue Apartment::DatabaseNotFound, Apartment::SchemaNotFound => e
69
+ puts e.message
70
+ end
43
71
  end
44
72
  end
45
73
 
@@ -48,9 +76,13 @@ apartment_namespace = namespace :apartment do
48
76
  version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
49
77
  raise 'VERSION is required' unless version
50
78
 
51
- Apartment.database_names.each do |db|
52
- puts("Migrating #{db} database down")
53
- Apartment::Migrator.run :down, db, version
79
+ database_names.each do |db|
80
+ begin
81
+ puts("Migrating #{db} database down")
82
+ Apartment::Migrator.run :down, db, version
83
+ rescue Apartment::DatabaseNotFound, Apartment::SchemaNotFound => e
84
+ puts e.message
85
+ end
54
86
  end
55
87
  end
56
88
 
@@ -67,4 +99,7 @@ apartment_namespace = namespace :apartment do
67
99
 
68
100
  end
69
101
 
70
- end
102
+ def database_names
103
+ ENV['DB'] ? ENV['DB'].split(',').map { |s| s.strip } : Apartment.database_names
104
+ end
105
+ end
@@ -18,7 +18,7 @@ if defined?(JRUBY_VERSION)
18
18
  ActiveRecord::Base.connection.execute("SELECT nspname FROM pg_namespace;").collect { |row| row['nspname'] }
19
19
  end
20
20
 
21
- let(:default_database) { subject.process { ActiveRecord::Base.connection.schema_search_path } }
21
+ let(:default_database) { subject.process { ActiveRecord::Base.connection.schema_search_path.gsub('"', '') } }
22
22
 
23
23
  it_should_behave_like "a generic apartment adapter"
24
24
  it_should_behave_like "a schema based apartment adapter"
@@ -40,4 +40,4 @@ if defined?(JRUBY_VERSION)
40
40
 
41
41
  end
42
42
  end
43
- end
43
+ end
@@ -16,7 +16,7 @@ describe Apartment::Adapters::PostgresqlAdapter do
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 } }
19
+ let(:default_database) { 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"
@@ -37,4 +37,4 @@ describe Apartment::Adapters::PostgresqlAdapter do
37
37
  it_should_behave_like "a connection based apartment adapter"
38
38
  end
39
39
  end
40
- end
40
+ end
@@ -44,6 +44,24 @@ describe Apartment::Database do
44
44
  end
45
45
 
46
46
  end
47
+
48
+ context "with prefix and schemas" do
49
+ describe "#create" do
50
+ before do
51
+ Apartment.configure do |config|
52
+ config.prepend_environment = true
53
+ config.use_schemas = true
54
+ end
55
+ subject.reload!(config) # switch to Mysql2SchemaAdapter
56
+ end
57
+
58
+ after { subject.drop "db_with_prefix" rescue nil }
59
+
60
+ it "should create a new database" do
61
+ subject.create "db_with_prefix"
62
+ end
63
+ end
64
+ end
47
65
  end
48
66
 
49
67
  context "using postgresql" do
@@ -4,10 +4,10 @@ shared_examples_for "an apartment elevator" do
4
4
 
5
5
  context "single request" do
6
6
  it "should switch the db" do
7
- ActiveRecord::Base.connection.schema_search_path.should_not == database1
7
+ ActiveRecord::Base.connection.schema_search_path.should_not == %{"#{database1}"}
8
8
 
9
9
  visit(domain1)
10
- ActiveRecord::Base.connection.schema_search_path.should == database1
10
+ ActiveRecord::Base.connection.schema_search_path.should == %{"#{database1}"}
11
11
  end
12
12
  end
13
13
 
@@ -48,11 +48,11 @@ shared_examples_for "a schema based apartment adapter" do
48
48
 
49
49
  subject.create(schema2) do
50
50
  @count = User.count
51
- connection.schema_search_path.should start_with schema2
51
+ connection.schema_search_path.should start_with %{"#{schema2}"}
52
52
  User.create
53
53
  end
54
54
 
55
- connection.schema_search_path.should_not start_with schema2
55
+ connection.schema_search_path.should_not start_with %{"#{schema2}"}
56
56
 
57
57
  subject.process(schema2){ User.count.should == @count + 1 }
58
58
  end
@@ -96,13 +96,13 @@ shared_examples_for "a schema based apartment adapter" do
96
96
  describe "#process" do
97
97
  it "should connect" do
98
98
  subject.process(schema1) do
99
- connection.schema_search_path.should start_with schema1
99
+ connection.schema_search_path.should start_with %{"#{schema1}"}
100
100
  end
101
101
  end
102
102
 
103
103
  it "should reset" do
104
104
  subject.process(schema1)
105
- connection.schema_search_path.should start_with public_schema
105
+ connection.schema_search_path.should start_with %{"#{public_schema}"}
106
106
  end
107
107
  end
108
108
 
@@ -110,14 +110,14 @@ shared_examples_for "a schema based apartment adapter" do
110
110
  it "should reset connection" do
111
111
  subject.switch(schema1)
112
112
  subject.reset
113
- connection.schema_search_path.should start_with public_schema
113
+ connection.schema_search_path.should start_with %{"#{public_schema}"}
114
114
  end
115
115
 
116
116
  context "with default_schema", :default_schema => true do
117
117
  it "should reset to the default schema" do
118
118
  subject.switch(schema1)
119
119
  subject.reset
120
- connection.schema_search_path.should start_with default_schema
120
+ connection.schema_search_path.should start_with %{"#{default_schema}"}
121
121
  end
122
122
  end
123
123
 
@@ -128,13 +128,13 @@ shared_examples_for "a schema based apartment adapter" do
128
128
  end
129
129
 
130
130
  it "maintains the persistent schemas in the schema_search_path" do
131
- connection.schema_search_path.should end_with persistent_schemas.join(', ')
131
+ connection.schema_search_path.should end_with persistent_schemas.map { |schema| %{"#{schema}"} }.join(', ')
132
132
  end
133
133
 
134
134
  context "with default_schema", :default_schema => true do
135
135
  it "prioritizes the switched schema to front of schema_search_path" do
136
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
137
+ connection.schema_search_path.should start_with %{"#{default_schema}"}
138
138
  end
139
139
  end
140
140
  end
@@ -143,12 +143,12 @@ shared_examples_for "a schema based apartment adapter" do
143
143
  describe "#switch" do
144
144
  it "should connect to new schema" do
145
145
  subject.switch(schema1)
146
- connection.schema_search_path.should start_with schema1
146
+ connection.schema_search_path.should start_with %{"#{schema1}"}
147
147
  end
148
148
 
149
149
  it "should reset connection if database is nil" do
150
150
  subject.switch
151
- connection.schema_search_path.should == public_schema
151
+ connection.schema_search_path.should == %{"#{public_schema}"}
152
152
  end
153
153
 
154
154
  it "should raise an error if schema is invalid" do
@@ -166,7 +166,7 @@ shared_examples_for "a schema based apartment adapter" do
166
166
  subject.switch(db)
167
167
  }.to_not raise_error
168
168
 
169
- connection.schema_search_path.should start_with db.to_s
169
+ connection.schema_search_path.should start_with %{"#{db.to_s}"}
170
170
  end
171
171
 
172
172
  after{ subject.drop(db) }
@@ -182,7 +182,7 @@ shared_examples_for "a schema based apartment adapter" do
182
182
  end
183
183
 
184
184
  it "should still switch to the switched schema" do
185
- connection.schema_search_path.should start_with schema1
185
+ connection.schema_search_path.should start_with %{"#{schema1}"}
186
186
  end
187
187
  end
188
188
 
@@ -191,11 +191,11 @@ shared_examples_for "a schema based apartment adapter" do
191
191
  before{ subject.switch(schema1) }
192
192
 
193
193
  it "maintains the persistent schemas in the schema_search_path" do
194
- connection.schema_search_path.should end_with persistent_schemas.join(', ')
194
+ connection.schema_search_path.should end_with persistent_schemas.map { |schema| %{"#{schema}"} }.join(', ')
195
195
  end
196
196
 
197
197
  it "prioritizes the switched schema to front of schema_search_path" do
198
- connection.schema_search_path.should start_with schema1
198
+ connection.schema_search_path.should start_with %{"#{schema1}"}
199
199
  end
200
200
  end
201
201
  end
@@ -215,4 +215,4 @@ shared_examples_for "a schema based apartment adapter" do
215
215
  end
216
216
  end
217
217
  end
218
- end
218
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Apartment::Elevators::HostHash do
4
+
5
+ describe "#parse_database_name" do
6
+ it "parses the host for a domain name" do
7
+ request = ActionDispatch::Request.new('HTTP_HOST' => 'example.com')
8
+ elevator = Apartment::Elevators::HostHash.new(nil, 'example.com' => 'example_database')
9
+ elevator.parse_database_name(request).should == 'example_database'
10
+ end
11
+
12
+ it "raises DatabaseNotFound exception if there is no host" do
13
+ request = ActionDispatch::Request.new('HTTP_HOST' => '')
14
+ elevator = Apartment::Elevators::HostHash.new(nil, 'example.com' => 'example_database')
15
+ expect { elevator.parse_database_name(request) }.to raise_error(Apartment::DatabaseNotFound)
16
+ end
17
+
18
+ it "raises DatabaseNotFound exception if there is no database associated to current host" do
19
+ request = ActionDispatch::Request.new('HTTP_HOST' => 'example2.com')
20
+ elevator = Apartment::Elevators::HostHash.new(nil, 'example.com' => 'example_database')
21
+ expect { elevator.parse_database_name(request) }.to raise_error(Apartment::DatabaseNotFound)
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -34,8 +34,8 @@ describe Apartment::Migrator do
34
34
 
35
35
  describe "#migrate" do
36
36
  it "should connect to new db, then reset when done" do
37
- ActiveRecord::Base.connection.should_receive(:schema_search_path=).with(schema_name).once
38
- ActiveRecord::Base.connection.should_receive(:schema_search_path=).with(@original_schema).once
37
+ ActiveRecord::Base.connection.should_receive(:schema_search_path=).with(%{"#{schema_name}"}).once
38
+ ActiveRecord::Base.connection.should_receive(:schema_search_path=).with(%{"#{@original_schema}"}).once
39
39
  Apartment::Migrator.migrate(schema_name)
40
40
  end
41
41
 
@@ -49,8 +49,8 @@ describe Apartment::Migrator do
49
49
  context "up" do
50
50
 
51
51
  it "should connect to new db, then reset when done" do
52
- ActiveRecord::Base.connection.should_receive(:schema_search_path=).with(schema_name).once
53
- ActiveRecord::Base.connection.should_receive(:schema_search_path=).with(@original_schema).once
52
+ ActiveRecord::Base.connection.should_receive(:schema_search_path=).with(%{"#{schema_name}"}).once
53
+ ActiveRecord::Base.connection.should_receive(:schema_search_path=).with(%{"#{@original_schema}"}).once
54
54
  Apartment::Migrator.run(:up, schema_name, version)
55
55
  end
56
56
 
@@ -63,8 +63,8 @@ describe Apartment::Migrator do
63
63
  describe "down" do
64
64
 
65
65
  it "should connect to new db, then reset when done" do
66
- ActiveRecord::Base.connection.should_receive(:schema_search_path=).with(schema_name).once
67
- ActiveRecord::Base.connection.should_receive(:schema_search_path=).with(@original_schema).once
66
+ ActiveRecord::Base.connection.should_receive(:schema_search_path=).with(%{"#{schema_name}"}).once
67
+ ActiveRecord::Base.connection.should_receive(:schema_search_path=).with(%{"#{@original_schema}"}).once
68
68
  Apartment::Migrator.run(:down, schema_name, version)
69
69
  end
70
70
 
@@ -86,4 +86,4 @@ describe Apartment::Migrator do
86
86
  end
87
87
  end
88
88
 
89
- end
89
+ end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apartment
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.1
5
- prerelease:
4
+ version: 0.22.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Ryan Brunner
@@ -10,38 +9,34 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2013-05-31 00:00:00.000000000 Z
12
+ date: 2013-07-09 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: activerecord
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
- - - ! '>='
18
+ - - '>='
21
19
  - !ruby/object:Gem::Version
22
20
  version: 3.1.2
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
- - - ! '>='
25
+ - - '>='
29
26
  - !ruby/object:Gem::Version
30
27
  version: 3.1.2
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: rack
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
- - - ! '>='
32
+ - - '>='
37
33
  - !ruby/object:Gem::Version
38
34
  version: 1.3.6
39
35
  type: :runtime
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
- - - ! '>='
39
+ - - '>='
45
40
  - !ruby/object:Gem::Version
46
41
  version: 1.3.6
47
42
  description: Apartment allows Rack applications to deal with database multitenancy
@@ -56,7 +51,8 @@ files:
56
51
  - .gitignore
57
52
  - .pryrc
58
53
  - .rspec
59
- - .rvmrc
54
+ - .ruby-gemset
55
+ - .ruby-version
60
56
  - .travis.yml
61
57
  - .vagrant
62
58
  - Cheffile
@@ -65,6 +61,7 @@ files:
65
61
  - HISTORY.md
66
62
  - README.md
67
63
  - Rakefile
64
+ - TODO.md
68
65
  - Vagrantfile
69
66
  - apartment.gemspec
70
67
  - circle.yml
@@ -87,12 +84,11 @@ files:
87
84
  - lib/apartment/elevators/domain.rb
88
85
  - lib/apartment/elevators/first_subdomain.rb
89
86
  - lib/apartment/elevators/generic.rb
87
+ - lib/apartment/elevators/host_hash.rb
90
88
  - lib/apartment/elevators/subdomain.rb
91
89
  - lib/apartment/migrator.rb
92
90
  - lib/apartment/railtie.rb
93
91
  - lib/apartment/reloader.rb
94
- - lib/apartment/sidekiq/client/database_middleware.rb
95
- - lib/apartment/sidekiq/server/database_middleware.rb
96
92
  - lib/apartment/version.rb
97
93
  - lib/generators/apartment/install/USAGE
98
94
  - lib/generators/apartment/install/install_generator.rb
@@ -161,39 +157,33 @@ files:
161
157
  - spec/tasks/apartment_rake_spec.rb
162
158
  - spec/unit/config_spec.rb
163
159
  - spec/unit/middleware/domain_elevator_spec.rb
160
+ - spec/unit/middleware/host_hash_elevator_spec.rb
164
161
  - spec/unit/middleware/subdomain_elevator_spec.rb
165
162
  - spec/unit/migrator_spec.rb
166
163
  - spec/unit/reloader_spec.rb
167
164
  homepage: https://github.com/influitive/apartment
168
165
  licenses:
169
166
  - MIT
167
+ metadata: {}
170
168
  post_install_message:
171
169
  rdoc_options: []
172
170
  require_paths:
173
171
  - lib
174
172
  required_ruby_version: !ruby/object:Gem::Requirement
175
- none: false
176
173
  requirements:
177
- - - ! '>='
174
+ - - '>='
178
175
  - !ruby/object:Gem::Version
179
176
  version: '0'
180
- segments:
181
- - 0
182
- hash: 2789245529283699970
183
177
  required_rubygems_version: !ruby/object:Gem::Requirement
184
- none: false
185
178
  requirements:
186
- - - ! '>='
179
+ - - '>='
187
180
  - !ruby/object:Gem::Version
188
181
  version: '0'
189
- segments:
190
- - 0
191
- hash: 2789245529283699970
192
182
  requirements: []
193
183
  rubyforge_project:
194
- rubygems_version: 1.8.25
184
+ rubygems_version: 2.0.3
195
185
  signing_key:
196
- specification_version: 3
186
+ specification_version: 4
197
187
  summary: A Ruby gem for managing database multitenancy
198
188
  test_files:
199
189
  - spec/adapters/jdbc_mysql_adapter_spec.rb
@@ -259,6 +249,7 @@ test_files:
259
249
  - spec/tasks/apartment_rake_spec.rb
260
250
  - spec/unit/config_spec.rb
261
251
  - spec/unit/middleware/domain_elevator_spec.rb
252
+ - spec/unit/middleware/host_hash_elevator_spec.rb
262
253
  - spec/unit/middleware/subdomain_elevator_spec.rb
263
254
  - spec/unit/migrator_spec.rb
264
255
  - spec/unit/reloader_spec.rb
data/.rvmrc DELETED
@@ -1 +0,0 @@
1
- rvm --create ruby-1.9.3@apartment
@@ -1,12 +0,0 @@
1
- module Apartment
2
- module Sidekiq
3
- module Client
4
- class DatabaseMiddleware
5
- def call(worker_class, item, queue)
6
- item["apartment"] = Apartment::Database.current_database
7
- yield
8
- end
9
- end
10
- end
11
- end
12
- end
@@ -1,13 +0,0 @@
1
- module Apartment
2
- module Sidekiq
3
- module Server
4
- class DatabaseMiddleware
5
- def call(worker_class, item, queue)
6
- Apartment::Database.process(item['apartment']) do
7
- yield
8
- end
9
- end
10
- end
11
- end
12
- end
13
- end