apartment 0.21.1 → 0.22.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.
@@ -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