apartment 0.24.3 → 0.25.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -2
  3. data/Appraisals +7 -3
  4. data/HISTORY.md +8 -0
  5. data/README.md +76 -21
  6. data/TODO.md +2 -2
  7. data/apartment.gemspec +17 -1
  8. data/gemfiles/{rails3.2.gemfile → rails_3_2.gemfile} +5 -1
  9. data/gemfiles/{rails4.0.gemfile → rails_4_0.gemfile} +5 -1
  10. data/gemfiles/rails_4_1.gemfile +11 -0
  11. data/lib/apartment.rb +2 -2
  12. data/lib/apartment/adapters/abstract_adapter.rb +1 -1
  13. data/lib/apartment/adapters/jdbc_mysql_adapter.rb +2 -2
  14. data/lib/apartment/adapters/jdbc_postgresql_adapter.rb +1 -1
  15. data/lib/apartment/adapters/mysql2_adapter.rb +3 -7
  16. data/lib/apartment/adapters/postgis_adapter.rb +2 -4
  17. data/lib/apartment/adapters/postgresql_adapter.rb +93 -8
  18. data/lib/apartment/adapters/sqlite3_adapter.rb +1 -1
  19. data/lib/apartment/console.rb +2 -2
  20. data/lib/apartment/elevators/generic.rb +2 -2
  21. data/lib/apartment/migrator.rb +1 -1
  22. data/lib/apartment/railtie.rb +3 -3
  23. data/lib/apartment/{database.rb → tenant.rb} +10 -3
  24. data/lib/apartment/version.rb +1 -1
  25. data/lib/generators/apartment/install/templates/apartment.rb +3 -0
  26. data/lib/tasks/apartment.rake +3 -3
  27. data/spec/adapters/jdbc_mysql_adapter_spec.rb +1 -1
  28. data/spec/adapters/jdbc_postgresql_adapter_spec.rb +1 -1
  29. data/spec/adapters/mysql2_adapter_spec.rb +2 -2
  30. data/spec/adapters/postgresql_adapter_spec.rb +17 -2
  31. data/spec/adapters/sqlite3_adapter_spec.rb +1 -1
  32. data/spec/apartment_spec.rb +4 -0
  33. data/spec/database_spec.rb +2 -2
  34. data/spec/examples/connection_adapter_examples.rb +1 -1
  35. data/spec/examples/schema_adapter_examples.rb +4 -4
  36. data/spec/integration/apartment_rake_integration_spec.rb +4 -4
  37. data/spec/integration/query_caching_spec.rb +7 -7
  38. data/spec/support/contexts.rb +1 -1
  39. data/spec/support/setup.rb +2 -2
  40. data/spec/unit/elevators/domain_spec.rb +1 -1
  41. data/spec/unit/elevators/generic_spec.rb +2 -2
  42. data/spec/unit/elevators/host_hash_spec.rb +1 -1
  43. data/spec/unit/elevators/subdomain_spec.rb +2 -2
  44. data/spec/unit/migrator_spec.rb +4 -4
  45. data/spec/unit/reloader_spec.rb +1 -1
  46. metadata +26 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 668ec9701ea4dbebdbae90b20283859a923e2e97
4
- data.tar.gz: 8f780f38eb0637204825f184a281118ea538cd25
3
+ metadata.gz: 7511a4af17aae3dc546bb1c76342c5b8301829c6
4
+ data.tar.gz: 819a8d11d7cf74fea4d67d9d7c364c92f6bf8aeb
5
5
  SHA512:
6
- metadata.gz: 1688f67d237510833030cde62b3e31a55b4c20dbcff96d74dcab1df3db19740722c40968beeabb392d141b77736d7ea96e76d5a0c9552ed5e644061dc3346483
7
- data.tar.gz: 31943cd1bc2650b5a7255ecfcceacdeb883878483476288ebc3e8318e3e911f9eece112e304634a7b3bcb98a779a42206308172d2493ef6c9b5e724615166cdd
6
+ metadata.gz: 67dbe1ad054395e0466e785b9c3d81d17b7ff97147a2e04f76b1af951a806045bd774e6a9cf4c372860389d9b63919cb22d742c6165b1d25bbe60505a1b41d9d
7
+ data.tar.gz: 4fd680bc07c8e12f5a88fc143a1a26c09c289b6ae9c3a96296b5d3b48137cfd680132a6aa2b1ac28e3316d9350dae1fe43c9c718b49088cdf1ff18366dfafee6
data/.travis.yml CHANGED
@@ -5,8 +5,9 @@ rvm:
5
5
  - 2.1.0
6
6
  - jruby-19mode
7
7
  gemfile:
8
- - gemfiles/rails3.2.gemfile
9
- - gemfiles/rails4.0.gemfile
8
+ - gemfiles/rails_3_2.gemfile
9
+ - gemfiles/rails_4_0.gemfile
10
+ - gemfiles/rails_4_1.gemfile
10
11
  bundler_args: --without local --verbose
11
12
  before_install:
12
13
  - gem install bundler -v '> 1.5.0'
data/Appraisals CHANGED
@@ -1,7 +1,11 @@
1
- appraise "rails3.2" do
1
+ appraise "rails-3-2" do
2
2
  gem "rails", "~> 3.2"
3
3
  end
4
4
 
5
- appraise "rails4.0" do
5
+ appraise "rails-4-0" do
6
6
  gem "rails", "~> 4.0"
7
- end
7
+ end
8
+
9
+ appraise "rails-4-1" do
10
+ gem "rails", "~> 4.1"
11
+ end
data/HISTORY.md CHANGED
@@ -1,3 +1,11 @@
1
+ # 0.25.0
2
+ * July 3, 2014
3
+
4
+ - [BREAKING CHANGE] - `Apartment::Database` is not deprecated in favour of
5
+ `Apartment::Tenant`
6
+ - ActiveRecord (and Rails) 4.1 now supported
7
+ - A new sql based adapter that dumps the schema using sql
8
+
1
9
  # 0.24.3
2
10
  * March 5, 2014
3
11
 
data/README.md CHANGED
@@ -43,7 +43,7 @@ Before you can switch to a new apartment tenant, you will need to create it. Whe
43
43
  you need to create a new tenant, you can run the following command:
44
44
 
45
45
  ```ruby
46
- Apartment::Database.create('tenant_name')
46
+ Apartment::Tenant.create('tenant_name')
47
47
  ```
48
48
 
49
49
  If you're using the [prepend environment](https://github.com/influitive/apartment#handling-environments) config option or you AREN'T using Postgresql Schemas, this will create a tenant in the following format: "#{environment}\_tenant_name".
@@ -67,7 +67,7 @@ One can optionally use the full database creation instead if they want, though t
67
67
  To switch tenants using Apartment, use the following command:
68
68
 
69
69
  ```ruby
70
- Apartment::Database.switch('tenant_name')
70
+ Apartment::Tenant.switch('tenant_name')
71
71
  ```
72
72
 
73
73
  When switch is called, all requests coming to ActiveRecord will be routed to the tenant
@@ -179,58 +179,101 @@ Rails will always access the 'public' tenant when accessing these models, but n
179
179
 
180
180
  ### Postgresql Schemas
181
181
 
182
- **Providing a Different default_schema**
182
+ ## Providing a Different default_schema
183
183
  By default, ActiveRecord will use `"$user", public` as the default `schema_search_path`. This can be modified if you wish to use a different default schema be setting:
184
184
 
185
185
  ```ruby
186
186
  config.default_schema = "some_other_schema"
187
187
  ```
188
188
 
189
- With that set, all excluded models will use this schema as the table name prefix instead of `public` and `reset` on `Apartment::Database` will return to this schema also
189
+ With that set, all excluded models will use this schema as the table name prefix instead of `public` and `reset` on `Apartment::Tenant` will return to this schema also
190
190
 
191
- **Persistent Schemas**
191
+ ## Persistent Schemas
192
192
  Apartment will normally just switch the `schema_search_path` whole hog to the one passed in. This can lead to problems if you want other schemas to always be searched as well. Enter `persistent_schemas`. You can configure a list of other schemas that will always remain in the search path, while the default gets swapped out:
193
193
 
194
194
  ```ruby
195
195
  config.persistent_schemas = ['some', 'other', 'schemas']
196
196
  ```
197
197
 
198
- This has numerous useful applications. [Hstore](http://www.postgresql.org/docs/9.1/static/hstore.html), for instance, is a popular storage engine for Postgresql. In order to use Hstore, you have to install it to a specific schema and have that always in the `schema_search_path`. This could be achieved like so:
198
+ ### Installing Extensions into Persistent Schemas
199
+ Persistent Schemas have numerous useful applications. [Hstore](http://www.postgresql.org/docs/9.1/static/hstore.html), for instance, is a popular storage engine for Postgresql. In order to use extensions such as Hstore, you have to install it to a specific schema and have that always in the `schema_search_path`.
200
+
201
+ When using extensions, keep in mind:
202
+ * Extensions can only be installed into one schema per database, so we will want to install it into a schema that is always available in the `schema_search_path`
203
+ * The schema and extension need to be created in the database *before* they are referenced in migrations, database.yml or apartment.
204
+ * There does not seem to be a way to create the schema and extension using standard rails migrations.
205
+ * Rails db:test:prepare deletes and recreates the database, so it needs to be easy for the extension schema to be recreated here.
206
+
207
+ #### 1. Ensure the extensions schema is created when the database is created
199
208
 
200
209
  ```ruby
201
- # NOTE do not do this in a migration, must be done
202
- # manually before you configure apartment with hstore
203
- # In a rake task, or on the console...
204
- ActiveRecord::Base.connection.execute("CREATE SCHEMA hstore; CREATE EXTENSION HSTORE SCHEMA hstore")
210
+ # lib/tasks/db_enhancements.rake
211
+
212
+ ####### Important information ####################
213
+ # This file is used to setup a shared extensions #
214
+ # within a dedicated schema. This gives us the #
215
+ # advantage of only needing to enable extensions #
216
+ # in one place. #
217
+ # #
218
+ # This task should be run AFTER db:create but #
219
+ # BEFORE db:migrate. #
220
+ ##################################################
221
+
222
+
223
+ namespace :db do
224
+ desc 'Also create shared_extensions Schema'
225
+ task :extensions => :environment do
226
+ # Create Schema
227
+ ActiveRecord::Base.connection.execute 'CREATE SCHEMA IF NOT EXISTS shared_extensions;'
228
+ # Enable Hstore
229
+ ActiveRecord::Base.connection.execute 'CREATE EXTENSION IF NOT EXISTS HSTORE SCHEMA shared_extensions;'
230
+ # Enable UUID-OSSP
231
+ ActiveRecord::Base.connection.execute 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp" SCHEMA shared_extensions;'
232
+ end
233
+ end
205
234
 
206
- # configure Apartment to maintain the `hstore` schema in the `schema_search_path`
207
- config.persistent_schemas = ['hstore']
208
- ```
235
+ Rake::Task["db:create"].enhance do
236
+ Rake::Task["db:extensions"].invoke
237
+ end
209
238
 
210
- There are a few caveats to be aware of when using `hstore`. First off, the hstore schema and extension creation need to be done manually *before* you reference it in any way in your migrations, database.yml or apartment. This is an unfortunate manual step, but I haven't found a way around it. You can achieve this from the command line using something like:
239
+ Rake::Task["db:test:purge"].enhance do
240
+ Rake::Task["db:extensions"].invoke
241
+ end
242
+ ```
211
243
 
212
- rails r 'ActiveRecord::Base.connection.execute("CREATE SCHEMA hstore; CREATE EXTENSION HSTORE SCHEMA hstore")'
244
+ #### 2. Ensure the schema is in Rails' default connection
213
245
 
214
- Next, your `database.yml` file must mimic what you've set for your default and persistent schemas in Apartment. When you run migrataions with Rails, it won't know about the hstore schema because Apartment isn't injected into the default connection, it's done on a per-request basis, therefore Rails doesn't know about `hstore` during migrations. To do so, add the following to your `database.yml` for all environments
246
+ Next, your `database.yml` file must mimic what you've set for your default and persistent schemas in Apartment. When you run migrataions with Rails, it won't know about the extensions schema because Apartment isn't injected into the default connection, it's done on a per-request basis, therefore Rails doesn't know about `hstore` or `uuid-ossp` during migrations. To do so, add the following to your `database.yml` for all environments
215
247
 
216
248
  ```yaml
217
249
  # database.yml
218
250
  ...
219
251
  adapter: postgresql
220
- schema_search_path: "public,hstore"
252
+ schema_search_path: "public,shared_extensions"
221
253
  ...
222
254
  ```
223
255
 
224
- This would be for a config with `default_schema` set to `public` and `persistent_schemas` set to `['hstore']`
256
+ This would be for a config with `default_schema` set to `public` and `persistent_schemas` set to `['shared_extensions']`. **Note**: This only works on Heroku with [Rails 4.1+](https://devcenter.heroku.com/changelog-items/427). For older Rails versions Heroku regenerates a completely different `database.yml` for each deploy and your predefined `schema_search_path` will be deleted. ActiveRecord's `schema_search_path` will be the default `\"$user\",public`.
257
+
258
+ #### 3. Ensure the schema is in the apartment config
259
+ ```ruby
260
+ # config/initializers/apartment.rb
261
+ ...
262
+ config.persistent_schemas = ['shared_extensions']
263
+ ...
264
+ ```
225
265
 
266
+ #### Alternative: Creating schema by default
226
267
  Another way that we've successfully configured hstore for our applications is to add it into the
227
268
  postgresql template1 database so that every tenant that gets created has it by default.
228
269
 
270
+ One caveat with this approach is that it can interfere with other projects in development using the same extensions and template, but not using apartment with this approach.
271
+
229
272
  You can do so using a command like so
230
273
 
231
274
  ```bash
232
- psql -U postgres -d template1 -c "CREATE SCHEMA hstore AUTHORIZATION some_username;"
233
- psql -U postgres -d template1 -c "CREATE EXTENSION IF NOT EXISTS hstore SCHEMA hstore;"
275
+ psql -U postgres -d template1 -c "CREATE SCHEMA shared_extensions AUTHORIZATION some_username;"
276
+ psql -U postgres -d template1 -c "CREATE EXTENSION IF NOT EXISTS hstore SCHEMA shared_extensions;"
234
277
  ```
235
278
 
236
279
  The *ideal* setup would actually be to install `hstore` into the `public` schema and leave the public
@@ -238,6 +281,18 @@ schema in the `search_path` at all times. We won't be able to do this though unt
238
281
  also contain the tenanted tables, which is an open issue with no real milestone to be completed.
239
282
  Happy to accept PR's on the matter.
240
283
 
284
+ #### Alternative: Creating new schemas by using raw SQL dumps
285
+ Apartment can be forced to use raw SQL dumps insted of `schema.rb` for creating new schemas. Use this when you are using some extra features in postgres that can't be respresented in `schema.rb`, like materialized views etc.
286
+
287
+ This only applies while using postgres adapter and `config.use_schemas` is set to `true`.
288
+ (Note: this option doesn't use `db/structure.sql`, it creates SQL dump by executing `pg_dump`)
289
+
290
+ Enable this option with:
291
+ ```ruby
292
+ config.use_sql = true
293
+ ```
294
+
295
+
241
296
  ### Managing Migrations
242
297
 
243
298
  In order to migrate all of your tenants (or posgresql schemas) you need to provide a list
@@ -258,7 +313,7 @@ You can then migrate your tenants using the normal rake task:
258
313
  rake db:migrate
259
314
  ```
260
315
 
261
- This just invokes `Apartment::Database.migrate(#{tenant_name})` for each tenant name supplied
316
+ This just invokes `Apartment::Tenant.migrate(#{tenant_name})` for each tenant name supplied
262
317
  from `Apartment.tenant_names`
263
318
 
264
319
  Note that you can disable the default migrating of all tenants with `db:migrate` by setting
data/TODO.md CHANGED
@@ -19,9 +19,9 @@
19
19
 
20
20
  This should ensure that going forward nothing breaks, and we should *ideally* be able to randomize the test order
21
21
 
22
- 2. `Apartment::Database` is the wrong abstraction. When dealing with a multi-tenanted system, users shouldn't thing about 'Databases', they should
22
+ 2. <del>`Apartment::Database` is the wrong abstraction. When dealing with a multi-tenanted system, users shouldn't thing about 'Databases', they should
23
23
  think about Tenants. I proprose that we deprecate the `Apartment::Database` constant in favour of `Apartment::Tenant` for a nicer abstraction. See
24
- http://myronmars.to/n/dev-blog/2011/09/deprecating-constants-and-classes-in-ruby for ideas on how to achieve this.
24
+ http://myronmars.to/n/dev-blog/2011/09/deprecating-constants-and-classes-in-ruby for ideas on how to achieve this.</del>
25
25
 
26
26
  4. Apartment::Database.process should be deprecated in favour of just passing a block to `switch`
27
27
  5. Apartment::Database.switch should be renamed to switch! to indicate that using it on its own has side effects
data/apartment.gemspec CHANGED
@@ -18,7 +18,23 @@ Gem::Specification.new do |s|
18
18
  s.homepage = %q{https://github.com/influitive/apartment}
19
19
  s.licenses = ["MIT"]
20
20
 
21
- s.add_dependency 'activerecord', '>= 3.1.2' # must be >= 3.1.2 due to bug in prepared_statements
21
+ s.post_install_message = <<-MSG
22
+ ********************************
23
+
24
+ Apartment Deprecation Warning
25
+
26
+ `Apartment::Database` has been deprecated in favour of `Apartment::Tenant`.
27
+ Please update your application to use the new constant as it is a more
28
+ appropriate abstraction.
29
+
30
+ To further this, DatabaseNotFound, SchemaNotFound, DatabaseExists and
31
+ SchemaExists exceptions will all be removed, you should instead use
32
+ TenantNotFound and TenantExists to catch any exceptions.
33
+
34
+ ********************************
35
+ MSG
36
+
37
+ s.add_dependency 'activerecord', '>= 3.1.2', '< 4.2' # must be >= 3.1.2 due to bug in prepared_statements
22
38
  s.add_dependency 'rack', '>= 1.3.6'
23
39
 
24
40
  s.add_development_dependency 'appraisal'
@@ -4,4 +4,8 @@ source "http://rubygems.org"
4
4
 
5
5
  gem "rails", "~> 3.2"
6
6
 
7
- gemspec :path=>"../"
7
+ group :local do
8
+ gem "pry"
9
+ end
10
+
11
+ gemspec :path => "../"
@@ -4,4 +4,8 @@ source "http://rubygems.org"
4
4
 
5
5
  gem "rails", "~> 4.0"
6
6
 
7
- gemspec :path=>"../"
7
+ group :local do
8
+ gem "pry"
9
+ end
10
+
11
+ gemspec :path => "../"
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 4.1"
6
+
7
+ group :local do
8
+ gem "pry"
9
+ end
10
+
11
+ gemspec :path => "../"
data/lib/apartment.rb CHANGED
@@ -2,7 +2,7 @@ require 'apartment/railtie' if defined?(Rails)
2
2
  require 'active_support/core_ext/object/blank'
3
3
  require 'forwardable'
4
4
  require 'active_record'
5
- require 'apartment/database'
5
+ require 'apartment/tenant'
6
6
 
7
7
  module Apartment
8
8
 
@@ -10,7 +10,7 @@ module Apartment
10
10
 
11
11
  extend Forwardable
12
12
 
13
- ACCESSOR_METHODS = [:use_schemas, :seed_after_create, :prepend_environment, :append_environment]
13
+ ACCESSOR_METHODS = [:use_schemas, :use_sql, :seed_after_create, :prepend_environment, :append_environment]
14
14
  WRITER_METHODS = [:tenant_names, :database_schema_file, :excluded_models, :default_schema, :persistent_schemas, :connection_class, :tld_length, :db_migrate_tenants]
15
15
 
16
16
  attr_accessor(*ACCESSOR_METHODS)
@@ -182,7 +182,7 @@ module Apartment
182
182
  # Exceptions to rescue from on db operations
183
183
  #
184
184
  def rescuable_exceptions
185
- [ActiveRecord::StatementInvalid] + [rescue_from].flatten
185
+ [ActiveRecord::ActiveRecordError] + [rescue_from].flatten
186
186
  end
187
187
 
188
188
  # Extra exceptions to rescue from
@@ -2,7 +2,7 @@ require "apartment/adapters/abstract_jdbc_adapter"
2
2
 
3
3
  module Apartment
4
4
 
5
- module Database
5
+ module Tenant
6
6
  def self.jdbc_mysql_adapter(config)
7
7
  Adapters::JDBCMysqlAdapter.new config
8
8
  end
@@ -22,7 +22,7 @@ module Apartment
22
22
  def connect_to_new(database)
23
23
  super
24
24
  rescue DatabaseNotFound
25
- Apartment::Database.reset
25
+ Apartment::Tenant.reset
26
26
  raise DatabaseNotFound, "Cannot find database #{environmentify(database)}"
27
27
  end
28
28
  end
@@ -1,7 +1,7 @@
1
1
  require 'apartment/adapters/postgresql_adapter'
2
2
 
3
3
  module Apartment
4
- module Database
4
+ module Tenant
5
5
 
6
6
  def self.jdbc_postgresql_adapter(config)
7
7
  Apartment.use_schemas ?
@@ -1,7 +1,7 @@
1
1
  require 'apartment/adapters/abstract_adapter'
2
2
 
3
3
  module Apartment
4
- module Database
4
+ module Tenant
5
5
 
6
6
  def self.mysql2_adapter(config)
7
7
  Apartment.use_schemas ?
@@ -24,7 +24,7 @@ module Apartment
24
24
  def connect_to_new(tenant = nil)
25
25
  super
26
26
  rescue Mysql2::Error
27
- Apartment::Database.reset
27
+ Apartment::Tenant.reset
28
28
  raise DatabaseNotFound, "Cannot find tenant #{environmentify(tenant)}"
29
29
  end
30
30
  end
@@ -61,16 +61,12 @@ module Apartment
61
61
  Apartment.connection.execute "use #{environmentify(tenant)}"
62
62
 
63
63
  rescue ActiveRecord::StatementInvalid
64
- Apartment::Database.reset
64
+ Apartment::Tenant.reset
65
65
  raise DatabaseNotFound, "Cannot find tenant #{environmentify(tenant)}"
66
66
  end
67
67
 
68
68
  def process_excluded_model(model)
69
69
  model.constantize.tap do |klass|
70
- # some models (such as delayed_job) seem to load and cache their column names before this,
71
- # so would never get the default prefix, so reset first
72
- klass.reset_column_information
73
-
74
70
  # Ensure that if a schema *was* set, we override
75
71
  table_name = klass.table_name.split('.', 2).last
76
72
 
@@ -3,12 +3,10 @@
3
3
  require "apartment/adapters/postgresql_adapter"
4
4
 
5
5
  module Apartment
6
- module Database
6
+ module Tenant
7
7
 
8
8
  def self.postgis_adapter(config)
9
- Apartment.use_schemas ?
10
- Adapters::PostgresqlSchemaAdapter.new(config) :
11
- Adapters::PostgresqlAdapter.new(config)
9
+ postgresql_adapter(config)
12
10
  end
13
11
  end
14
12
  end
@@ -1,12 +1,13 @@
1
1
  require 'apartment/adapters/abstract_adapter'
2
2
 
3
3
  module Apartment
4
- module Database
4
+ module Tenant
5
5
 
6
6
  def self.postgresql_adapter(config)
7
- Apartment.use_schemas ?
8
- Adapters::PostgresqlSchemaAdapter.new(config) :
9
- Adapters::PostgresqlAdapter.new(config)
7
+ adapter = Adapters::PostgresqlAdapter
8
+ adapter = Adapters::PostgresqlSchemaAdapter if Apartment.use_schemas
9
+ adapter = Adapters::PostgresqlSchemaFromSqlAdapter if Apartment.use_sql && Apartment.use_schemas
10
+ adapter.new(config)
10
11
  end
11
12
  end
12
13
 
@@ -55,10 +56,6 @@ module Apartment
55
56
  def process_excluded_models
56
57
  Apartment.excluded_models.each do |excluded_model|
57
58
  excluded_model.constantize.tap do |klass|
58
- # some models (such as delayed_job) seem to load and cache their column names before this,
59
- # so would never get the default prefix, so reset first
60
- klass.reset_column_information
61
-
62
59
  # Ensure that if a schema *was* set, we override
63
60
  table_name = klass.table_name.split('.', 2).last
64
61
 
@@ -116,5 +113,93 @@ module Apartment
116
113
  [@current_tenant, Apartment.persistent_schemas].flatten
117
114
  end
118
115
  end
116
+
117
+ # Another Adapter for Postgresql when using schemas and SQL
118
+ class PostgresqlSchemaFromSqlAdapter < PostgresqlSchemaAdapter
119
+
120
+ PSQL_DUMP_BLACKLISTED_STATEMENTS= [
121
+ /SET search_path/i, # overridden later
122
+ /SET lock_timeout/i # new in postgresql 9.3
123
+ ]
124
+
125
+ def import_database_schema
126
+ clone_pg_schema
127
+ copy_schema_migrations
128
+ end
129
+
130
+ private
131
+
132
+ # Clone default schema into new schema named after current tenant
133
+ #
134
+ def clone_pg_schema
135
+ pg_schema_sql = patch_search_path(pg_dump_schema)
136
+ Apartment.connection.execute(pg_schema_sql)
137
+ end
138
+
139
+ # Copy data from schema_migrations into new schema
140
+ #
141
+ def copy_schema_migrations
142
+ pg_migrations_data = patch_search_path(pg_dump_schema_migrations_data)
143
+ Apartment.connection.execute(pg_migrations_data)
144
+ end
145
+
146
+ # Dump postgres default schema
147
+ #
148
+ # @return {String} raw SQL contaning only postgres schema dump
149
+ #
150
+ def pg_dump_schema
151
+ dbname = ActiveRecord::Base.connection_config[:database]
152
+ default_schema = Apartment.default_schema
153
+
154
+ # Skip excluded tables? :/
155
+ # excluded_tables =
156
+ # collect_table_names(Apartment.excluded_models)
157
+ # .map! {|t| "-T #{t}"}
158
+ # .join(' ')
159
+
160
+ # `pg_dump -s -x -O -n #{default_schema} #{excluded_tables} #{dbname}`
161
+
162
+ `pg_dump -s -x -O -n #{default_schema} #{dbname}`
163
+ end
164
+
165
+ # Dump data from schema_migrations table
166
+ #
167
+ # @return {String} raw SQL contaning inserts with data from schema_migrations
168
+ #
169
+ def pg_dump_schema_migrations_data
170
+ `pg_dump -a --inserts -t schema_migrations -n #{Apartment.default_schema} bithub_development`
171
+ end
172
+
173
+ # Remove "SET search_path ..." line from SQL dump and prepend search_path set to current tenant
174
+ #
175
+ # @return {String} patched raw SQL dump
176
+ #
177
+ def patch_search_path(sql)
178
+ search_path = "SET search_path = #{self.current_tenant}, #{Apartment.default_schema};"
179
+
180
+ sql
181
+ .split("\n")
182
+ .select {|line| check_input_against_regexps(line, PSQL_DUMP_BLACKLISTED_STATEMENTS).empty?}
183
+ .prepend(search_path)
184
+ .join("\n")
185
+ end
186
+
187
+ # Checks if any of regexps matches against input
188
+ #
189
+ def check_input_against_regexps(input, regexps)
190
+ regexps.select {|c| input.match c}
191
+ end
192
+
193
+ # Collect table names from AR Models
194
+ #
195
+ def collect_table_names(models)
196
+ models.map do |m|
197
+ m.constantize.table_name
198
+ end
199
+ end
200
+
201
+ end
202
+
203
+
119
204
  end
120
205
  end
@@ -1,7 +1,7 @@
1
1
  require 'apartment/adapters/abstract_adapter'
2
2
 
3
3
  module Apartment
4
- module Database
4
+ module Tenant
5
5
  def self.sqlite3_adapter(config)
6
6
  Adapters::Sqlite3Adapter.new(config)
7
7
  end
@@ -1,4 +1,4 @@
1
- # A workaraound to get `reload!` to also call Apartment::Database.init
1
+ # A workaraound to get `reload!` to also call Apartment::Tenant.init
2
2
  # This is unfortunate, but I haven't figured out how to hook into the reload process *after* files are reloaded
3
3
 
4
4
  # reloads the environment
@@ -7,6 +7,6 @@ def reload!(print=true)
7
7
  # This triggers the to_prepare callbacks
8
8
  ActionDispatch::Callbacks.new(Proc.new {}).call({})
9
9
  # Manually init Apartment again once classes are reloaded
10
- Apartment::Database.init
10
+ Apartment::Tenant.init
11
11
  true
12
12
  end
@@ -1,5 +1,5 @@
1
1
  require 'rack/request'
2
- require 'apartment/database'
2
+ require 'apartment/tenant'
3
3
 
4
4
  module Apartment
5
5
  module Elevators
@@ -17,7 +17,7 @@ module Apartment
17
17
 
18
18
  database = @processor.call(request)
19
19
 
20
- Apartment::Database.switch database if database
20
+ Apartment::Tenant.switch database if database
21
21
 
22
22
  @app.call(env)
23
23
  end
@@ -1,4 +1,4 @@
1
- require 'apartment/database'
1
+ require 'apartment/tenant'
2
2
 
3
3
  module Apartment
4
4
  module Migrator
@@ -1,5 +1,5 @@
1
1
  require 'rails'
2
- require 'apartment/database'
2
+ require 'apartment/tenant'
3
3
  require 'apartment/reloader'
4
4
 
5
5
  module Apartment
@@ -28,7 +28,7 @@ module Apartment
28
28
  # See the middleware/console declarations below to help with this. Hope to fix that soon.
29
29
  #
30
30
  config.to_prepare do
31
- Apartment::Database.init
31
+ Apartment::Tenant.init
32
32
  end
33
33
 
34
34
  #
@@ -50,7 +50,7 @@ module Apartment
50
50
  app.config.middleware.use "Apartment::Reloader"
51
51
  end
52
52
 
53
- # Overrides reload! to also call Apartment::Database.init as well so that the reloaded classes have the proper table_names
53
+ # Overrides reload! to also call Apartment::Tenant.init as well so that the reloaded classes have the proper table_names
54
54
  console do
55
55
  require 'apartment/console'
56
56
  end
@@ -3,7 +3,7 @@ require 'forwardable'
3
3
  module Apartment
4
4
  # The main entry point to Apartment functions
5
5
  #
6
- module Database
6
+ module Tenant
7
7
 
8
8
  extend self
9
9
  extend Forwardable
@@ -60,7 +60,14 @@ module Apartment
60
60
  # Fetch the rails database configuration
61
61
  #
62
62
  def config
63
- @config ||= Rails.configuration.database_configuration[Rails.env].symbolize_keys
63
+ @config ||= (ActiveRecord::Base.configurations[Rails.env] ||
64
+ Rails.application.config.database_configuration[Rails.env]).symbolize_keys
64
65
  end
65
66
  end
66
- end
67
+
68
+ def self.const_missing(const_name)
69
+ super unless const_name == :Database
70
+ warn "`Apartment::Database` has been deprecated. Use `Apartment::Tenant` instead."
71
+ Tenant
72
+ end
73
+ end
@@ -1,3 +1,3 @@
1
1
  module Apartment
2
- VERSION = "0.24.3"
2
+ VERSION = "0.25.0"
3
3
  end
@@ -22,6 +22,9 @@ Apartment.configure do |config|
22
22
  # use postgres schemas?
23
23
  config.use_schemas = true
24
24
 
25
+ # use raw SQL dumps for creating postgres schemas? (only appies with use_schemas set to true)
26
+ #config.use_sql = true
27
+
25
28
  # configure persistent schemas (E.g. hstore )
26
29
  # config.persistent_schemas = %w{ hstore }
27
30
 
@@ -7,7 +7,7 @@ apartment_namespace = namespace :apartment do
7
7
  tenants.each do |tenant|
8
8
  begin
9
9
  puts("Creating #{tenant} tenant")
10
- quietly { Apartment::Database.create(tenant) }
10
+ quietly { Apartment::Tenant.create(tenant) }
11
11
  rescue Apartment::TenantExists => e
12
12
  puts e.message
13
13
  end
@@ -35,8 +35,8 @@ apartment_namespace = namespace :apartment do
35
35
  tenants.each do |tenant|
36
36
  begin
37
37
  puts("Seeding #{tenant} tenant")
38
- Apartment::Database.process(tenant) do
39
- Apartment::Database.seed
38
+ Apartment::Tenant.process(tenant) do
39
+ Apartment::Tenant.seed
40
40
  end
41
41
  rescue Apartment::TenantNotFound => e
42
42
  puts e.message
@@ -5,7 +5,7 @@ if defined?(JRUBY_VERSION)
5
5
 
6
6
  describe Apartment::Adapters::JDBCMysqlAdapter, database: :mysql do
7
7
 
8
- subject { Apartment::Database.jdbc_mysql_adapter config.symbolize_keys }
8
+ subject { Apartment::Tenant.jdbc_mysql_adapter config.symbolize_keys }
9
9
 
10
10
  def tenant_names
11
11
  ActiveRecord::Base.connection.execute("SELECT schema_name FROM information_schema.schemata").collect { |row| row['schema_name'] }
@@ -5,7 +5,7 @@ if defined?(JRUBY_VERSION)
5
5
 
6
6
  describe Apartment::Adapters::JDBCPostgresqlAdapter, database: :postgresql do
7
7
 
8
- subject { Apartment::Database.jdbc_postgresql_adapter config.symbolize_keys }
8
+ subject { Apartment::Tenant.jdbc_postgresql_adapter config.symbolize_keys }
9
9
 
10
10
  context "using schemas" do
11
11
 
@@ -4,7 +4,7 @@ require 'apartment/adapters/mysql2_adapter'
4
4
  describe Apartment::Adapters::Mysql2Adapter, database: :mysql do
5
5
  unless defined?(JRUBY_VERSION)
6
6
 
7
- subject(:adapter){ Apartment::Database.mysql2_adapter config }
7
+ subject(:adapter){ Apartment::Tenant.mysql2_adapter config }
8
8
 
9
9
  def tenant_names
10
10
  ActiveRecord::Base.connection.execute("SELECT schema_name FROM information_schema.schemata").collect { |row| row[0] }
@@ -31,7 +31,7 @@ describe Apartment::Adapters::Mysql2Adapter, database: :mysql do
31
31
  end
32
32
 
33
33
  it "should process model exclusions" do
34
- Apartment::Database.init
34
+ Apartment::Tenant.init
35
35
 
36
36
  Company.table_name.should == "#{default_tenant}.companies"
37
37
  end
@@ -4,9 +4,9 @@ require 'apartment/adapters/postgresql_adapter'
4
4
  describe Apartment::Adapters::PostgresqlAdapter, database: :postgresql do
5
5
  unless defined?(JRUBY_VERSION)
6
6
 
7
- subject{ Apartment::Database.postgresql_adapter config }
7
+ subject{ Apartment::Tenant.postgresql_adapter config }
8
8
 
9
- context "using schemas" do
9
+ context "using schemas with schema.rb" do
10
10
 
11
11
  before{ Apartment.use_schemas = true }
12
12
 
@@ -21,6 +21,21 @@ describe Apartment::Adapters::PostgresqlAdapter, database: :postgresql do
21
21
  it_should_behave_like "a schema based apartment adapter"
22
22
  end
23
23
 
24
+ context "using schemas with SQL dump" do
25
+
26
+ before{ Apartment.use_schemas = true; Apartment.use_sql = true }
27
+
28
+ # Not sure why, but somehow using let(:tenant_names) memoizes for the whole example group, not just each test
29
+ def tenant_names
30
+ ActiveRecord::Base.connection.execute("SELECT nspname FROM pg_namespace;").collect { |row| row['nspname'] }
31
+ end
32
+
33
+ let(:default_tenant) { subject.process { ActiveRecord::Base.connection.schema_search_path.gsub('"', '') } }
34
+
35
+ it_should_behave_like "a generic apartment adapter"
36
+ it_should_behave_like "a schema based apartment adapter"
37
+ end
38
+
24
39
  context "using connections" do
25
40
 
26
41
  before{ Apartment.use_schemas = false }
@@ -4,7 +4,7 @@ require 'apartment/adapters/sqlite3_adapter'
4
4
  describe Apartment::Adapters::Sqlite3Adapter, database: :sqlite do
5
5
  unless defined?(JRUBY_VERSION)
6
6
 
7
- subject{ Apartment::Database.sqlite3_adapter config }
7
+ subject{ Apartment::Tenant.sqlite3_adapter config }
8
8
 
9
9
  context "using connections" do
10
10
  def tenant_names
@@ -8,4 +8,8 @@ describe Apartment do
8
8
  it "should be a valid app" do
9
9
  ::Rails.application.should be_a(Dummy::Application)
10
10
  end
11
+
12
+ it "should deprecate Apartment::Database in favor of Apartment::Tenant" do
13
+ expect(Apartment::Database).to eq(Apartment::Tenant)
14
+ end
11
15
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Apartment::Database do
3
+ describe Apartment::Tenant do
4
4
  context "using mysql", database: :mysql do
5
5
 
6
6
  before do
@@ -77,7 +77,7 @@ describe Apartment::Database do
77
77
  subject.stub(:config).and_return config.merge(:adapter => 'unknown')
78
78
 
79
79
  expect {
80
- Apartment::Database.adapter
80
+ Apartment::Tenant.adapter
81
81
  }.to raise_error
82
82
  end
83
83
 
@@ -10,7 +10,7 @@ shared_examples_for "a connection based apartment adapter" do
10
10
  Apartment.configure do |config|
11
11
  config.excluded_models = ["Company"]
12
12
  end
13
- Apartment::Database.init
13
+ Apartment::Tenant.init
14
14
 
15
15
  Company.connection.object_id.should_not == ActiveRecord::Base.connection.object_id
16
16
  end
@@ -16,7 +16,7 @@ shared_examples_for "a schema based apartment adapter" do
16
16
  end
17
17
 
18
18
  it "should process model exclusions" do
19
- Apartment::Database.init
19
+ Apartment::Tenant.init
20
20
 
21
21
  Company.table_name.should == "public.companies"
22
22
  end
@@ -24,13 +24,13 @@ shared_examples_for "a schema based apartment adapter" do
24
24
  context "with a default_schema", :default_schema => true do
25
25
 
26
26
  it "should set the proper table_name on excluded_models" do
27
- Apartment::Database.init
27
+ Apartment::Tenant.init
28
28
 
29
29
  Company.table_name.should == "#{default_schema}.companies"
30
30
  end
31
31
 
32
32
  it 'sets the search_path correctly' do
33
- Apartment::Database.init
33
+ Apartment::Tenant.init
34
34
 
35
35
  User.connection.schema_search_path.should =~ %r|#{default_schema}|
36
36
  end
@@ -38,7 +38,7 @@ shared_examples_for "a schema based apartment adapter" do
38
38
 
39
39
  context "persistent_schemas", :persistent_schemas => true do
40
40
  it "sets the persistent schemas in the schema_search_path" do
41
- Apartment::Database.init
41
+ Apartment::Tenant.init
42
42
  connection.schema_search_path.should end_with persistent_schemas.map { |schema| %{"#{schema}"} }.join(', ')
43
43
  end
44
44
  end
@@ -21,7 +21,7 @@ describe "apartment rake tasks", database: :postgresql do
21
21
  config.excluded_models = ["Company"]
22
22
  config.tenant_names = lambda{ Company.pluck(:database) }
23
23
  end
24
- Apartment::Database.reload!(config)
24
+ Apartment::Tenant.reload!(config)
25
25
 
26
26
  # fix up table name of shared/excluded models
27
27
  Company.table_name = 'public.companies'
@@ -37,13 +37,13 @@ describe "apartment rake tasks", database: :postgresql do
37
37
 
38
38
  before do
39
39
  db_names.collect do |db_name|
40
- Apartment::Database.create(db_name)
40
+ Apartment::Tenant.create(db_name)
41
41
  Company.create :database => db_name
42
42
  end
43
43
  end
44
44
 
45
45
  after do
46
- db_names.each{ |db| Apartment::Database.drop(db) }
46
+ db_names.each{ |db| Apartment::Tenant.drop(db) }
47
47
  Company.delete_all
48
48
  end
49
49
 
@@ -65,7 +65,7 @@ describe "apartment rake tasks", database: :postgresql do
65
65
 
66
66
  describe "apartment:seed" do
67
67
  it "should seed all databases" do
68
- Apartment::Database.should_receive(:seed).exactly(company_count).times
68
+ Apartment::Tenant.should_receive(:seed).exactly(company_count).times
69
69
 
70
70
  @rake['apartment:seed'].invoke
71
71
  end
@@ -10,32 +10,32 @@ describe 'query caching' do
10
10
  config.use_schemas = true
11
11
  end
12
12
 
13
- Apartment::Database.reload!(config)
13
+ Apartment::Tenant.reload!(config)
14
14
 
15
15
  db_names.each do |db_name|
16
- Apartment::Database.create(db_name)
16
+ Apartment::Tenant.create(db_name)
17
17
  Company.create database: db_name
18
18
  end
19
19
  end
20
20
 
21
21
  after do
22
- db_names.each{ |db| Apartment::Database.drop(db) }
23
- Apartment::Database.reset
22
+ db_names.each{ |db| Apartment::Tenant.drop(db) }
23
+ Apartment::Tenant.reset
24
24
  Company.delete_all
25
25
  end
26
26
 
27
27
  it 'clears the ActiveRecord::QueryCache after switching databases' do
28
28
  db_names.each do |db_name|
29
- Apartment::Database.switch db_name
29
+ Apartment::Tenant.switch db_name
30
30
  User.create! name: db_name
31
31
  end
32
32
 
33
33
  ActiveRecord::Base.connection.enable_query_cache!
34
34
 
35
- Apartment::Database.switch db_names.first
35
+ Apartment::Tenant.switch db_names.first
36
36
  User.find_by_name(db_names.first).name.should == db_names.first
37
37
 
38
- Apartment::Database.switch db_names.last
38
+ Apartment::Tenant.switch db_names.last
39
39
  User.find_by_name(db_names.first).should be_nil
40
40
  end
41
41
  end
@@ -20,7 +20,7 @@ shared_context "elevators", elevator: true do
20
20
  let(:company1) { mock_model(Company, database: db1).as_null_object }
21
21
  let(:company2) { mock_model(Company, database: db2).as_null_object }
22
22
 
23
- let(:api) { Apartment::Database }
23
+ let(:api) { Apartment::Tenant }
24
24
 
25
25
  before do
26
26
  Apartment.reset # reset all config
@@ -15,7 +15,7 @@ module Apartment
15
15
  # Otherwise these actually get run after test defined hooks
16
16
  around(:each) do |example|
17
17
  # before
18
- Apartment::Database.reload!(config)
18
+ Apartment::Tenant.reload!(config)
19
19
  ActiveRecord::Base.establish_connection config
20
20
 
21
21
  example.run
@@ -33,7 +33,7 @@ module Apartment
33
33
  end
34
34
 
35
35
  Apartment.reset
36
- Apartment::Database.reload!
36
+ Apartment::Tenant.reload!
37
37
  end
38
38
  end
39
39
  end
@@ -24,7 +24,7 @@ describe Apartment::Elevators::Domain do
24
24
 
25
25
  describe "#call" do
26
26
  it "switches to the proper tenant" do
27
- Apartment::Database.should_receive(:switch).with('example')
27
+ Apartment::Tenant.should_receive(:switch).with('example')
28
28
 
29
29
  elevator.call('HTTP_HOST' => 'www.example.com')
30
30
  end
@@ -15,7 +15,7 @@ describe Apartment::Elevators::Generic do
15
15
  it "calls the processor if given" do
16
16
  elevator = described_class.new(Proc.new{}, Proc.new{'tenant1'})
17
17
 
18
- Apartment::Database.should_receive(:switch).with('tenant1')
18
+ Apartment::Tenant.should_receive(:switch).with('tenant1')
19
19
 
20
20
  elevator.call('HTTP_HOST' => 'foo.bar.com')
21
21
  end
@@ -29,7 +29,7 @@ describe Apartment::Elevators::Generic do
29
29
  it "switches to the parsed db_name" do
30
30
  elevator = MyElevator.new(Proc.new{})
31
31
 
32
- Apartment::Database.should_receive(:switch).with('tenant2')
32
+ Apartment::Tenant.should_receive(:switch).with('tenant2')
33
33
 
34
34
  elevator.call('HTTP_HOST' => 'foo.bar.com')
35
35
  end
@@ -24,7 +24,7 @@ describe Apartment::Elevators::HostHash do
24
24
 
25
25
  describe "#call" do
26
26
  it "switches to the proper tenant" do
27
- Apartment::Database.should_receive(:switch).with('example_tenant')
27
+ Apartment::Tenant.should_receive(:switch).with('example_tenant')
28
28
 
29
29
  elevator.call('HTTP_HOST' => 'example.com')
30
30
  end
@@ -39,14 +39,14 @@ describe Apartment::Elevators::Subdomain do
39
39
 
40
40
  describe "#call" do
41
41
  it "switches to the proper tenant" do
42
- Apartment::Database.should_receive(:switch).with('tenant1')
42
+ Apartment::Tenant.should_receive(:switch).with('tenant1')
43
43
  elevator.call('HTTP_HOST' => 'tenant1.example.com')
44
44
  end
45
45
 
46
46
  it "ignores excluded subdomains" do
47
47
  described_class.excluded_subdomains = %w{foo}
48
48
 
49
- Apartment::Database.should_not_receive(:switch)
49
+ Apartment::Tenant.should_not_receive(:switch)
50
50
 
51
51
  elevator.call('HTTP_HOST' => 'foo.bar.com')
52
52
 
@@ -6,11 +6,11 @@ describe Apartment::Migrator do
6
6
  let(:tenant){ Apartment::Test.next_db }
7
7
 
8
8
  # Don't need a real switch here, just testing behaviour
9
- before { Apartment::Database.adapter.stub(:connect_to_new) }
9
+ before { Apartment::Tenant.adapter.stub(:connect_to_new) }
10
10
 
11
11
  describe "::migrate" do
12
12
  it "processes and migrates" do
13
- expect(Apartment::Database).to receive(:process).with(tenant).and_call_original
13
+ expect(Apartment::Tenant).to receive(:process).with(tenant).and_call_original
14
14
  expect(ActiveRecord::Migrator).to receive(:migrate)
15
15
 
16
16
  Apartment::Migrator.migrate(tenant)
@@ -19,7 +19,7 @@ describe Apartment::Migrator do
19
19
 
20
20
  describe "::run" do
21
21
  it "processes and runs" do
22
- expect(Apartment::Database).to receive(:process).with(tenant).and_call_original
22
+ expect(Apartment::Tenant).to receive(:process).with(tenant).and_call_original
23
23
  expect(ActiveRecord::Migrator).to receive(:run).with(:up, anything, 1234)
24
24
 
25
25
  Apartment::Migrator.run(:up, tenant, 1234)
@@ -28,7 +28,7 @@ describe Apartment::Migrator do
28
28
 
29
29
  describe "::rollback" do
30
30
  it "processes and rolls back" do
31
- expect(Apartment::Database).to receive(:process).with(tenant).and_call_original
31
+ expect(Apartment::Tenant).to receive(:process).with(tenant).and_call_original
32
32
  expect(ActiveRecord::Migrator).to receive(:rollback).with(anything, 2)
33
33
 
34
34
  Apartment::Migrator.rollback(tenant, 2)
@@ -9,7 +9,7 @@ describe Apartment::Reloader do
9
9
  config.excluded_models = ["Company"]
10
10
  config.use_schemas = true
11
11
  end
12
- Apartment::Database.reload!(config)
12
+ Apartment::Tenant.reload!(config)
13
13
  Company.reset_table_name # ensure we're clean
14
14
  end
15
15
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apartment
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.24.3
4
+ version: 0.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Brunner
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-03-05 00:00:00.000000000 Z
12
+ date: 2014-07-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -18,6 +18,9 @@ dependencies:
18
18
  - - '>='
19
19
  - !ruby/object:Gem::Version
20
20
  version: 3.1.2
21
+ - - <
22
+ - !ruby/object:Gem::Version
23
+ version: '4.2'
21
24
  type: :runtime
22
25
  prerelease: false
23
26
  version_requirements: !ruby/object:Gem::Requirement
@@ -25,6 +28,9 @@ dependencies:
25
28
  - - '>='
26
29
  - !ruby/object:Gem::Version
27
30
  version: 3.1.2
31
+ - - <
32
+ - !ruby/object:Gem::Version
33
+ version: '4.2'
28
34
  - !ruby/object:Gem::Dependency
29
35
  name: rack
30
36
  requirement: !ruby/object:Gem::Requirement
@@ -174,8 +180,9 @@ files:
174
180
  - Rakefile
175
181
  - TODO.md
176
182
  - apartment.gemspec
177
- - gemfiles/rails3.2.gemfile
178
- - gemfiles/rails4.0.gemfile
183
+ - gemfiles/rails_3_2.gemfile
184
+ - gemfiles/rails_4_0.gemfile
185
+ - gemfiles/rails_4_1.gemfile
179
186
  - lib/apartment.rb
180
187
  - lib/apartment/adapters/abstract_adapter.rb
181
188
  - lib/apartment/adapters/abstract_jdbc_adapter.rb
@@ -186,7 +193,6 @@ files:
186
193
  - lib/apartment/adapters/postgresql_adapter.rb
187
194
  - lib/apartment/adapters/sqlite3_adapter.rb
188
195
  - lib/apartment/console.rb
189
- - lib/apartment/database.rb
190
196
  - lib/apartment/elevators/domain.rb
191
197
  - lib/apartment/elevators/first_subdomain.rb
192
198
  - lib/apartment/elevators/generic.rb
@@ -196,6 +202,7 @@ files:
196
202
  - lib/apartment/railtie.rb
197
203
  - lib/apartment/reloader.rb
198
204
  - lib/apartment/tasks/enhancements.rb
205
+ - lib/apartment/tenant.rb
199
206
  - lib/apartment/version.rb
200
207
  - lib/generators/apartment/install/USAGE
201
208
  - lib/generators/apartment/install/install_generator.rb
@@ -271,7 +278,20 @@ homepage: https://github.com/influitive/apartment
271
278
  licenses:
272
279
  - MIT
273
280
  metadata: {}
274
- post_install_message:
281
+ post_install_message: |2
282
+ ********************************
283
+
284
+ Apartment Deprecation Warning
285
+
286
+ `Apartment::Database` has been deprecated in favour of `Apartment::Tenant`.
287
+ Please update your application to use the new constant as it is a more
288
+ appropriate abstraction.
289
+
290
+ To further this, DatabaseNotFound, SchemaNotFound, DatabaseExists and
291
+ SchemaExists exceptions will all be removed, you should instead use
292
+ TenantNotFound and TenantExists to catch any exceptions.
293
+
294
+ ********************************
275
295
  rdoc_options: []
276
296
  require_paths:
277
297
  - lib