apartment 0.22.1 → 0.23.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -2
- data/.rspec +2 -1
- data/.travis.yml +3 -1
- data/Appraisals +7 -0
- data/Gemfile +0 -21
- data/HISTORY.md +6 -0
- data/README.md +13 -71
- data/Rakefile +4 -2
- data/TODO.md +0 -5
- data/apartment.gemspec +19 -0
- data/gemfiles/rails3.2.gemfile +7 -0
- data/gemfiles/rails4.0.gemfile +7 -0
- data/lib/apartment.rb +2 -28
- data/lib/apartment/adapters/abstract_adapter.rb +0 -2
- data/lib/apartment/adapters/abstract_jdbc_adapter.rb +2 -0
- data/lib/apartment/adapters/jdbc_mysql_adapter.rb +2 -0
- data/lib/apartment/adapters/jdbc_postgresql_adapter.rb +1 -1
- data/lib/apartment/adapters/mysql2_adapter.rb +2 -3
- data/lib/apartment/adapters/postgis_adapter.rb +0 -1
- data/lib/apartment/adapters/postgresql_adapter.rb +2 -3
- data/lib/apartment/adapters/sqlite3_adapter.rb +2 -0
- data/lib/apartment/database.rb +0 -4
- data/lib/apartment/elevators/domain.rb +2 -0
- data/lib/apartment/elevators/first_subdomain.rb +2 -0
- data/lib/apartment/elevators/generic.rb +3 -0
- data/lib/apartment/elevators/host_hash.rb +2 -0
- data/lib/apartment/elevators/subdomain.rb +19 -2
- data/lib/apartment/migrator.rb +2 -1
- data/lib/apartment/railtie.rb +2 -2
- data/lib/apartment/reloader.rb +0 -3
- data/lib/apartment/version.rb +2 -2
- data/lib/tasks/apartment.rake +2 -0
- data/spec/adapters/jdbc_mysql_adapter_spec.rb +1 -3
- data/spec/adapters/jdbc_postgresql_adapter_spec.rb +1 -3
- data/spec/adapters/mysql2_adapter_spec.rb +1 -2
- data/spec/adapters/postgresql_adapter_spec.rb +1 -2
- data/spec/adapters/sqlite3_adapter_spec.rb +1 -2
- data/spec/database_spec.rb +32 -50
- data/spec/dummy/app/models/user.rb +0 -2
- data/spec/dummy/config/application.rb +2 -0
- data/spec/dummy/config/environments/development.rb +2 -0
- data/spec/dummy/config/environments/production.rb +2 -0
- data/spec/dummy/config/environments/test.rb +1 -2
- data/spec/dummy/config/initializers/apartment.rb +1 -1
- data/spec/dummy/db/seeds.rb +1 -4
- data/spec/examples/elevator_examples.rb +4 -4
- data/spec/integration/apartment_rake_integration_spec.rb +15 -19
- data/spec/integration/middleware/domain_elevator_spec.rb +4 -3
- data/spec/integration/middleware/generic_elevator_spec.rb +4 -3
- data/spec/integration/middleware/subdomain_elevator_spec.rb +29 -3
- data/spec/integration/query_caching_spec.rb +8 -4
- data/spec/schemas/v1.rb +16 -0
- data/spec/schemas/v2.rb +43 -0
- data/spec/schemas/v3.rb +49 -0
- data/spec/spec_helper.rb +5 -11
- data/spec/support/apartment_helpers.rb +4 -2
- data/spec/support/contexts.rb +15 -19
- data/spec/support/requirements.rb +1 -17
- data/spec/support/setup.rb +47 -0
- data/spec/tasks/apartment_rake_spec.rb +6 -3
- data/spec/unit/config_spec.rb +3 -3
- data/spec/unit/middleware/domain_elevator_spec.rb +1 -2
- data/spec/{integration → unit}/middleware/first_subdomain_elevator_spec.rb +1 -0
- data/spec/unit/middleware/host_hash_elevator_spec.rb +1 -2
- data/spec/unit/middleware/subdomain_elevator_spec.rb +1 -2
- data/spec/unit/migrator_spec.rb +5 -4
- data/spec/unit/reloader_spec.rb +6 -4
- metadata +130 -14
- data/lib/apartment/delayed_job/enqueue.rb +0 -26
- data/lib/apartment/delayed_job/hooks.rb +0 -26
- data/lib/apartment/delayed_job/psych_ext.rb +0 -61
- data/lib/apartment/delayed_job/requirements.rb +0 -23
- data/lib/apartment/delayed_job/syck_ext.rb +0 -29
- data/spec/dummy/lib/fake_dj_class.rb +0 -6
- data/spec/integration/delayed_job_integration_spec.rb +0 -99
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7048e41db332f308d96362525ecd55389c7b6ad2
|
4
|
+
data.tar.gz: c303cac42eca0c9d5a22263fb8d2b3abb239b07e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab730aab830bf546295ecd75dabc017dd1fe01a55bbf82b625ff0f9e70cd7a58034417afe25344c7c36ff9f9e1f75eec7a73a4d07432fc1f6acc4e03291548ab
|
7
|
+
data.tar.gz: 0d7041eaea15f04e43ab772adfbbebb51f35451215a619882162d337d9bb25bbffbf3c9bbfb0e73ece50935681a45adc8d1ecb55e9d1ceeae38823a2dbd73134
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/.travis.yml
CHANGED
data/Appraisals
ADDED
data/Gemfile
CHANGED
@@ -3,27 +3,6 @@ source 'http://rubygems.org'
|
|
3
3
|
gemspec
|
4
4
|
|
5
5
|
gem 'rails', '>= 3.1.2'
|
6
|
-
gem 'rake', '~> 0.9'
|
7
|
-
gem 'rspec', '~> 2.11'
|
8
|
-
gem 'rspec-rails', '~> 2.11'
|
9
|
-
gem 'capybara', '~> 1.0.0'
|
10
|
-
gem 'delayed_job', '~> 3.0'
|
11
|
-
gem 'delayed_job_active_record'
|
12
|
-
|
13
|
-
platform :ruby do
|
14
|
-
gem 'mysql2', '~> 0.3.10'
|
15
|
-
gem 'pg', '>= 0.11.0'
|
16
|
-
gem 'sqlite3'
|
17
|
-
end
|
18
|
-
|
19
|
-
platform :jruby do
|
20
|
-
gem 'activerecord-jdbc-adapter'
|
21
|
-
gem 'activerecord-jdbcpostgresql-adapter'
|
22
|
-
gem 'activerecord-jdbcmysql-adapter'
|
23
|
-
gem 'jdbc-postgres', '9.2.1002'
|
24
|
-
gem 'jdbc-mysql'
|
25
|
-
gem 'jruby-openssl'
|
26
|
-
end
|
27
6
|
|
28
7
|
group :local do
|
29
8
|
gem 'pry'
|
data/HISTORY.md
CHANGED
data/README.md
CHANGED
@@ -75,19 +75,28 @@ In house, we use the subdomain elevator, which analyzes the subdomain of the req
|
|
75
75
|
|
76
76
|
```ruby
|
77
77
|
# application.rb
|
78
|
-
module
|
78
|
+
module MyApplication
|
79
79
|
class Application < Rails::Application
|
80
80
|
config.middleware.use 'Apartment::Elevators::Subdomain'
|
81
81
|
end
|
82
82
|
end
|
83
83
|
```
|
84
84
|
|
85
|
+
If you want to exclude a domain, for example if you don't want your application to treate www like a subdomain, in an initializer in your application, you can set the following:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
# config/initializers/apartment/subdomain_exclusions.rb
|
89
|
+
Apartment::Elevators::Subdomain.excluded_subdomains = ['www']
|
90
|
+
```
|
91
|
+
|
92
|
+
This functions much in the same way as Apartment.excluded_models. This example will prevent switching your database when the subdomain is www. Handy for subdomains like: "public", "www", and "admin" :)
|
93
|
+
|
85
94
|
**Switch on domain**
|
86
95
|
To switch based on full domain (excluding subdomains *ie 'www'* and top level domains *ie '.com'* ) use the following:
|
87
96
|
|
88
97
|
```ruby
|
89
98
|
# application.rb
|
90
|
-
module
|
99
|
+
module MyApplication
|
91
100
|
class Application < Rails::Application
|
92
101
|
config.middleware.use 'Apartment::Elevators::Domain'
|
93
102
|
end
|
@@ -99,7 +108,7 @@ To switch based on full host with a hash to find corresponding database name use
|
|
99
108
|
|
100
109
|
```ruby
|
101
110
|
# application.rb
|
102
|
-
module
|
111
|
+
module MyApplication
|
103
112
|
class Application < Rails::Application
|
104
113
|
config.middleware.use 'Apartment::Elevators::HostHash', {'example.com' => 'example_database'}
|
105
114
|
end
|
@@ -238,74 +247,7 @@ config.prepend_environment = !Rails.env.production?
|
|
238
247
|
```
|
239
248
|
|
240
249
|
## Delayed::Job
|
241
|
-
|
242
|
-
### Read me before using Delayed::Job!!!
|
243
|
-
> It should be noted that we now consider Delayed::Job usage with Apartment effectively deprecated
|
244
|
-
> It will be stripped out into it's own gem for backwards compatibility, but we've had far too
|
245
|
-
> many problems with it to continue supporting it.
|
246
|
-
>
|
247
|
-
> The main problem is that Delayed::Job [monkey](https://github.com/collectiveidea/delayed_job/blob/master/lib/delayed/psych_ext.rb) [patches](https://github.com/collectiveidea/delayed_job/blob/master/lib/delayed/syck_ext.rb) YAML quite a bit, which
|
248
|
-
> forces us to in tern [monkey](https://github.com/influitive/apartment/blob/development/lib/apartment/delayed_job/psych_ext.rb) [patch](https://github.com/influitive/apartment/blob/development/lib/apartment/delayed_job/syck_ext.rb) their monkey patches, which provides
|
249
|
-
> no end of frustrations whenever upgrades are made.
|
250
|
-
>
|
251
|
-
> To this end, we recommend you look into other solutions such as Resque or Sidekiq and write
|
252
|
-
> your own hooks to switch db per job. Our aim is to have separate gems for each of these
|
253
|
-
> worker libs and would love it if anyone would like to contribute something to achieve this
|
254
|
-
>
|
255
|
-
> If you are hell bent on using `Delayed::Job`, this is what has worked for us in Production
|
256
|
-
>
|
257
|
-
> ```ruby
|
258
|
-
> gem 'delayed_job', '= 3.0.1' # change at own risk!
|
259
|
-
> gem 'delayed_job_active_record', '= 0.3.2' # change at own risk!
|
260
|
-
> ```
|
261
|
-
>
|
262
|
-
|
263
|
-
If using Rails ~> 3.2, you *must* use `delayed_job ~> 3.0`. It has better Rails 3 support plus has some major changes that affect the serialization of models.
|
264
|
-
|
265
|
-
### If using Ruby 1.9.3-p362 you MUST use psych as your parser. YAML seems to fall down using syck
|
266
|
-
|
267
|
-
### If you're using syck on an earlier version of ruby, here's what you must do (in a rails app for instance)
|
268
|
-
This can be done in the `boot.rb` of your rails config *just above* where Bundler requires the gems from the Gemfile. It will look something like:
|
269
|
-
|
270
|
-
```ruby
|
271
|
-
require 'rubygems'
|
272
|
-
require 'yaml'
|
273
|
-
YAML::ENGINE.yamler = 'syck'
|
274
|
-
|
275
|
-
# Set up gems listed in the Gemfile.
|
276
|
-
gemfile = File.expand_path('../../Gemfile', __FILE__)
|
277
|
-
# ...
|
278
|
-
```
|
279
|
-
|
280
|
-
In order to make ActiveRecord models play nice with DJ and Apartment, include `Apartment::Delayed::Requirements` in any model that is being serialized by DJ. Also ensure that the `database` attribute (provided by Apartment::Delayed::Requirements) is set on this model *before* it is serialized, to ensure that when it is fetched again, it is done so in the proper Apartment db context. For example:
|
281
|
-
|
282
|
-
```ruby
|
283
|
-
class SomeModel < ActiveRecord::Base
|
284
|
-
include Apartment::Delayed::Requirements
|
285
|
-
end
|
286
|
-
```
|
287
|
-
|
288
|
-
Any classes that are being used as a Delayed::Job Job need to include the `Apartment::Delayed::Job::Hooks` module into the class. This ensures that when a job runs, it switches to the appropriate tenant before performing its task. It is also required (manually at the moment) that you set a `@database` attribute on your job so the hooks know what tennant to switch to
|
289
|
-
|
290
|
-
```ruby
|
291
|
-
class SomeDJ
|
292
|
-
include Apartment::Delayed::Job::Hooks
|
293
|
-
|
294
|
-
def initialize
|
295
|
-
@database = Apartment::Database.current_database
|
296
|
-
end
|
297
|
-
|
298
|
-
def perform
|
299
|
-
# do some stuff (will automatically switch to @database before performing and switch back after)
|
300
|
-
end
|
301
|
-
end
|
302
|
-
```
|
303
|
-
|
304
|
-
All jobs *must* stored in the global (public) namespace, so add it to the list of excluded models:
|
305
|
-
|
306
|
-
```ruby
|
307
|
-
config.excluded_models = ["Delayed::Job"]
|
308
|
-
```
|
250
|
+
### Has been removed... See apartment-sidekiq for a better backgrounding experience
|
309
251
|
|
310
252
|
## Contributing
|
311
253
|
|
data/Rakefile
CHANGED
@@ -2,6 +2,8 @@ require 'bundler' rescue 'You must `gem install bundler` and `bundle install` to
|
|
2
2
|
Bundler.setup
|
3
3
|
Bundler::GemHelper.install_tasks
|
4
4
|
|
5
|
+
require 'appraisal'
|
6
|
+
|
5
7
|
require "rspec"
|
6
8
|
require "rspec/core/rake_task"
|
7
9
|
|
@@ -63,7 +65,7 @@ namespace :mysql do
|
|
63
65
|
|
64
66
|
desc 'Build the MySQL test databases'
|
65
67
|
task :build_db do
|
66
|
-
%x{ mysqladmin -u #{my_config['username']} create #{my_config['database']} } rescue "test db already exists"
|
68
|
+
%x{ mysqladmin -u #{my_config['username']} --password=#{my_config['password']} create #{my_config['database']} } rescue "test db already exists"
|
67
69
|
ActiveRecord::Base.establish_connection my_config
|
68
70
|
ActiveRecord::Migrator.migrate('spec/dummy/db/migrate')
|
69
71
|
end
|
@@ -71,7 +73,7 @@ namespace :mysql do
|
|
71
73
|
desc "drop the MySQL test database"
|
72
74
|
task :drop_db do
|
73
75
|
puts "dropping database #{my_config['database']}"
|
74
|
-
%x{ mysqladmin -u #{my_config['username']} drop #{my_config['database']} --force}
|
76
|
+
%x{ mysqladmin -u #{my_config['username']} --password=#{my_config['password']} drop #{my_config['database']} --force}
|
75
77
|
end
|
76
78
|
|
77
79
|
end
|
data/TODO.md
CHANGED
@@ -24,11 +24,6 @@
|
|
24
24
|
think about Tenants. I proprose that we deprecate the `Apartment::Database` constant in favour of `Apartment::Tenant` for a nicer abstraction. See
|
25
25
|
http://myronmars.to/n/dev-blog/2011/09/deprecating-constants-and-classes-in-ruby for ideas on how to achieve this.
|
26
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
27
|
4. Apartment::Database.process should be deprecated in favour of just passing an optional block to `switch`
|
33
28
|
|
34
29
|
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
|
data/apartment.gemspec
CHANGED
@@ -20,4 +20,23 @@ Gem::Specification.new do |s|
|
|
20
20
|
|
21
21
|
s.add_dependency 'activerecord', '>= 3.1.2' # must be >= 3.1.2 due to bug in prepared_statements
|
22
22
|
s.add_dependency 'rack', '>= 1.3.6'
|
23
|
+
|
24
|
+
s.add_development_dependency 'appraisal'
|
25
|
+
s.add_development_dependency 'rake', '~> 0.9'
|
26
|
+
s.add_development_dependency 'rspec', '~> 2.11'
|
27
|
+
s.add_development_dependency 'rspec-rails', '~> 2.11'
|
28
|
+
s.add_development_dependency 'capybara', '~> 1.0.0'
|
29
|
+
|
30
|
+
if defined?(JRUBY_VERSION)
|
31
|
+
s.add_development_dependency 'activerecord-jdbc-adapter'
|
32
|
+
s.add_development_dependency 'activerecord-jdbcpostgresql-adapter'
|
33
|
+
s.add_development_dependency 'activerecord-jdbcmysql-adapter'
|
34
|
+
s.add_development_dependency 'jdbc-postgres', '9.2.1002'
|
35
|
+
s.add_development_dependency 'jdbc-mysql'
|
36
|
+
s.add_development_dependency 'jruby-openssl'
|
37
|
+
else
|
38
|
+
s.add_development_dependency 'mysql2', '~> 0.3.10'
|
39
|
+
s.add_development_dependency 'pg', '>= 0.11.0'
|
40
|
+
s.add_development_dependency 'sqlite3'
|
41
|
+
end
|
23
42
|
end
|
data/lib/apartment.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'apartment/railtie' if defined?(Rails)
|
2
2
|
require 'active_support/core_ext/object/blank'
|
3
3
|
require 'forwardable'
|
4
|
+
require 'active_record'
|
5
|
+
require 'apartment/database'
|
4
6
|
|
5
7
|
module Apartment
|
6
8
|
|
@@ -63,33 +65,6 @@ module Apartment
|
|
63
65
|
warn "[Deprecation Warning] `use_postgresql_schemas=` is now deprecated, please use `use_schemas=`"
|
64
66
|
self.use_schemas = to_use_or_not_to_use
|
65
67
|
end
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
autoload :Database, 'apartment/database'
|
70
|
-
autoload :Migrator, 'apartment/migrator'
|
71
|
-
autoload :Reloader, 'apartment/reloader'
|
72
|
-
|
73
|
-
module Adapters
|
74
|
-
autoload :AbstractAdapter, 'apartment/adapters/abstract_adapter'
|
75
|
-
# Specific adapters will be loaded dynamically based on adapter in config
|
76
|
-
end
|
77
|
-
|
78
|
-
module Elevators
|
79
|
-
autoload :Generic, 'apartment/elevators/generic'
|
80
|
-
autoload :Subdomain, 'apartment/elevators/subdomain'
|
81
|
-
autoload :FirstSubdomain, 'apartment/elevators/first_subdomain'
|
82
|
-
autoload :Domain, 'apartment/elevators/domain'
|
83
|
-
autoload :HostHash, 'apartment/elevators/host_hash'
|
84
|
-
end
|
85
|
-
|
86
|
-
module Delayed
|
87
|
-
|
88
|
-
autoload :Requirements, 'apartment/delayed_job/requirements'
|
89
|
-
|
90
|
-
module Job
|
91
|
-
autoload :Hooks, 'apartment/delayed_job/hooks'
|
92
|
-
end
|
93
68
|
end
|
94
69
|
|
95
70
|
# Exceptions
|
@@ -112,5 +87,4 @@ module Apartment
|
|
112
87
|
|
113
88
|
# Raised when an ActiveRecord object does not have the required database field on it
|
114
89
|
class DJSerializationError < ApartmentError; end
|
115
|
-
|
116
90
|
end
|
@@ -48,7 +48,7 @@ module Apartment
|
|
48
48
|
#
|
49
49
|
def connect_to_new(database = nil)
|
50
50
|
return reset if database.nil?
|
51
|
-
raise ActiveRecord::StatementInvalid.new unless Apartment.connection.all_schemas.include? database.to_s
|
51
|
+
raise ActiveRecord::StatementInvalid.new("Could not find schema #{database}") unless Apartment.connection.all_schemas.include? database.to_s
|
52
52
|
|
53
53
|
@current_database = database.to_s
|
54
54
|
Apartment.connection.schema_search_path = full_search_path
|
@@ -1,5 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'apartment/adapters/abstract_adapter'
|
2
2
|
|
3
|
+
module Apartment
|
3
4
|
module Database
|
4
5
|
|
5
6
|
def self.mysql2_adapter(config)
|
@@ -10,7 +11,6 @@ module Apartment
|
|
10
11
|
end
|
11
12
|
|
12
13
|
module Adapters
|
13
|
-
|
14
14
|
class Mysql2Adapter < AbstractAdapter
|
15
15
|
|
16
16
|
protected
|
@@ -73,7 +73,6 @@ module Apartment
|
|
73
73
|
# Ensure that if a schema *was* set, we override
|
74
74
|
table_name = klass.table_name.split('.', 2).last
|
75
75
|
|
76
|
-
# Not sure why, but Delayed::Job somehow ignores table_name_prefix... so we'll just manually set table name instead
|
77
76
|
klass.table_name = "#{default_database}.#{table_name}"
|
78
77
|
end
|
79
78
|
end
|
@@ -1,5 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'apartment/adapters/abstract_adapter'
|
2
2
|
|
3
|
+
module Apartment
|
3
4
|
module Database
|
4
5
|
|
5
6
|
def self.postgresql_adapter(config)
|
@@ -10,7 +11,6 @@ module Apartment
|
|
10
11
|
end
|
11
12
|
|
12
13
|
module Adapters
|
13
|
-
|
14
14
|
# Default adapter when not using Postgresql Schemas
|
15
15
|
class PostgresqlAdapter < AbstractAdapter
|
16
16
|
|
@@ -48,7 +48,6 @@ module Apartment
|
|
48
48
|
# Ensure that if a schema *was* set, we override
|
49
49
|
table_name = klass.table_name.split('.', 2).last
|
50
50
|
|
51
|
-
# Not sure why, but Delayed::Job somehow ignores table_name_prefix... so we'll just manually set table name instead
|
52
51
|
klass.table_name = "#{Apartment.default_schema}.#{table_name}"
|
53
52
|
end
|
54
53
|
end
|
data/lib/apartment/database.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
|
3
3
|
module Apartment
|
4
|
-
|
5
4
|
# The main entry point to Apartment functions
|
6
5
|
#
|
7
6
|
module Database
|
@@ -36,7 +35,6 @@ module Apartment
|
|
36
35
|
end
|
37
36
|
|
38
37
|
begin
|
39
|
-
require "apartment/adapters/abstract_jdbc_adapter" if defined?(JRUBY_VERSION)
|
40
38
|
require "apartment/adapters/#{adapter_method}"
|
41
39
|
rescue LoadError
|
42
40
|
raise "The adapter `#{adapter_method}` is not yet supported"
|
@@ -64,7 +62,5 @@ module Apartment
|
|
64
62
|
def config
|
65
63
|
@config ||= Rails.configuration.database_configuration[Rails.env].symbolize_keys
|
66
64
|
end
|
67
|
-
|
68
65
|
end
|
69
|
-
|
70
66
|
end
|