apartment 0.21.0 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.travis.yml +1 -0
- data/Gemfile +2 -1
- data/HISTORY.md +6 -0
- data/README.md +1 -1
- data/lib/apartment/adapters/abstract_adapter.rb +18 -14
- data/lib/apartment/adapters/abstract_jdbc_adapter.rb +7 -37
- data/lib/apartment/adapters/jdbc_postgresql_adapter.rb +19 -79
- data/lib/apartment/adapters/postgresql_adapter.rb +8 -23
- data/lib/apartment/adapters/sqlite3_adapter.rb +51 -0
- data/lib/apartment/elevators/first_subdomain.rb +6 -5
- data/lib/apartment/version.rb +1 -1
- data/spec/adapters/sqlite3_adapter_spec.rb +28 -0
- data/spec/config/database.yml.sample +5 -1
- data/spec/integration/delayed_job_integration_spec.rb +18 -8
- data/spec/integration/query_caching_spec.rb +37 -0
- metadata +43 -39
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/HISTORY.md
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Apartment
|
2
|
-
[](https://codeclimate.com/github/influitive/apartment)
|
3
3
|
[](http://travis-ci.org/influitive/apartment)
|
4
4
|
|
5
5
|
*Multitenancy for Rails 3 and ActiveRecord*
|
@@ -1,9 +1,7 @@
|
|
1
1
|
require 'active_record'
|
2
2
|
|
3
3
|
module Apartment
|
4
|
-
|
5
4
|
module Adapters
|
6
|
-
|
7
5
|
class AbstractAdapter
|
8
6
|
|
9
7
|
# @constructor
|
@@ -52,7 +50,7 @@ module Apartment
|
|
52
50
|
# Apartment.connection.drop_database note that drop_database will not throw an exception, so manually execute
|
53
51
|
Apartment.connection.execute("DROP DATABASE #{environmentify(database)}" )
|
54
52
|
|
55
|
-
rescue
|
53
|
+
rescue *rescuable_exceptions
|
56
54
|
raise DatabaseNotFound, "The database #{environmentify(database)} cannot be found"
|
57
55
|
end
|
58
56
|
|
@@ -74,13 +72,6 @@ module Apartment
|
|
74
72
|
def process_excluded_models
|
75
73
|
# All other models will shared a connection (at Apartment.connection_class) and we can modify at will
|
76
74
|
Apartment.excluded_models.each do |excluded_model|
|
77
|
-
# Note that due to rails reloading, we now take string references to classes rather than
|
78
|
-
# actual object references. This way when we contantize, we always get the proper class reference
|
79
|
-
if excluded_model.is_a? Class
|
80
|
-
warn "[Deprecation Warning] Passing class references to excluded models is now deprecated, please use a string instead"
|
81
|
-
excluded_model = excluded_model.name
|
82
|
-
end
|
83
|
-
|
84
75
|
excluded_model.constantize.establish_connection @config
|
85
76
|
end
|
86
77
|
end
|
@@ -99,7 +90,9 @@ module Apartment
|
|
99
90
|
# Just connect to default db and return
|
100
91
|
return reset if database.nil?
|
101
92
|
|
102
|
-
connect_to_new(database)
|
93
|
+
connect_to_new(database).tap do
|
94
|
+
ActiveRecord::Base.connection.clear_query_cache
|
95
|
+
end
|
103
96
|
end
|
104
97
|
|
105
98
|
# Load the rails seed file into the db
|
@@ -118,7 +111,7 @@ module Apartment
|
|
118
111
|
def create_database(database)
|
119
112
|
Apartment.connection.create_database( environmentify(database) )
|
120
113
|
|
121
|
-
rescue
|
114
|
+
rescue *rescuable_exceptions
|
122
115
|
raise DatabaseExists, "The database #{environmentify(database)} already exists."
|
123
116
|
end
|
124
117
|
|
@@ -130,7 +123,7 @@ module Apartment
|
|
130
123
|
Apartment.establish_connection multi_tenantify(database)
|
131
124
|
Apartment.connection.active? # call active? to manually check if this connection is valid
|
132
125
|
|
133
|
-
rescue
|
126
|
+
rescue *rescuable_exceptions
|
134
127
|
raise DatabaseNotFound, "The database #{environmentify(database)} cannot be found."
|
135
128
|
end
|
136
129
|
|
@@ -179,6 +172,17 @@ module Apartment
|
|
179
172
|
end
|
180
173
|
end
|
181
174
|
|
175
|
+
# Exceptions to rescue from on db operations
|
176
|
+
#
|
177
|
+
def rescuable_exceptions
|
178
|
+
[ActiveRecord::StatementInvalid] + [rescue_from].flatten
|
179
|
+
end
|
180
|
+
|
181
|
+
# Extra exceptions to rescue from
|
182
|
+
#
|
183
|
+
def rescue_from
|
184
|
+
[]
|
185
|
+
end
|
182
186
|
end
|
183
187
|
end
|
184
|
-
end
|
188
|
+
end
|
@@ -1,43 +1,8 @@
|
|
1
1
|
module Apartment
|
2
|
-
|
3
2
|
module Adapters
|
4
|
-
|
5
3
|
class AbstractJDBCAdapter < AbstractAdapter
|
6
4
|
|
7
|
-
|
8
|
-
#
|
9
|
-
# @param {String} database Database name
|
10
|
-
#
|
11
|
-
def drop(database)
|
12
|
-
super(database)
|
13
|
-
|
14
|
-
rescue ActiveRecord::StatementInvalid, ActiveRecord::JDBCError
|
15
|
-
raise DatabaseNotFound, "The database #{environmentify(database)} cannot be found"
|
16
|
-
end
|
17
|
-
|
18
|
-
protected
|
19
|
-
|
20
|
-
# Create the database
|
21
|
-
#
|
22
|
-
# @param {String} database Database name
|
23
|
-
#
|
24
|
-
def create_database(database)
|
25
|
-
super(database)
|
26
|
-
|
27
|
-
rescue ActiveRecord::StatementInvalid, ActiveRecord::JDBCError
|
28
|
-
raise DatabaseExists, "The database #{environmentify(database)} already exists."
|
29
|
-
end
|
30
|
-
|
31
|
-
# Connect to new database
|
32
|
-
#
|
33
|
-
# @param {String} database Database name
|
34
|
-
#
|
35
|
-
def connect_to_new(database)
|
36
|
-
super(database)
|
37
|
-
|
38
|
-
rescue ActiveRecord::StatementInvalid, ActiveRecord::JDBCError
|
39
|
-
raise DatabaseNotFound, "The database #{environmentify(database)} cannot be found."
|
40
|
-
end
|
5
|
+
protected
|
41
6
|
|
42
7
|
# Return a new config that is multi-tenanted
|
43
8
|
#
|
@@ -46,6 +11,11 @@ module Apartment
|
|
46
11
|
config[:url] = "#{config[:url].gsub(/(\S+)\/.+$/, '\1')}/#{environmentify(database)}"
|
47
12
|
end
|
48
13
|
end
|
14
|
+
private
|
15
|
+
|
16
|
+
def rescue_from
|
17
|
+
ActiveRecord::JDBCError
|
18
|
+
end
|
49
19
|
end
|
50
20
|
end
|
51
|
-
end
|
21
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'apartment/adapters/postgresql_adapter'
|
2
2
|
|
3
|
+
module Apartment
|
3
4
|
module Database
|
4
5
|
|
5
6
|
def self.jdbc_postgresql_adapter(config)
|
@@ -12,91 +13,42 @@ module Apartment
|
|
12
13
|
module Adapters
|
13
14
|
|
14
15
|
# Default adapter when not using Postgresql Schemas
|
15
|
-
class JDBCPostgresqlAdapter <
|
16
|
+
class JDBCPostgresqlAdapter < PostgresqlAdapter
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
# Connect to new database
|
20
|
-
# Abstract adapter will catch generic ActiveRecord error
|
21
|
-
# Catch specific adapter errors here
|
22
|
-
#
|
23
|
-
# @param {String} database Database name
|
24
|
-
#
|
25
|
-
def connect_to_new(database)
|
26
|
-
super(database)
|
27
|
-
rescue ActiveRecord::StatementInvalid, ActiveRecord::JDBCError
|
28
|
-
raise DatabaseNotFound, "Cannot find database #{environmentify(database)}"
|
29
|
-
end
|
18
|
+
protected
|
30
19
|
|
31
20
|
def create_database(database)
|
32
21
|
# There is a bug in activerecord-jdbcpostgresql-adapter (1.2.5) that will cause
|
33
22
|
# an exception if no options are passed into the create_database call.
|
34
23
|
Apartment.connection.create_database(environmentify(database), { :thisisahack => '' })
|
35
24
|
|
36
|
-
rescue
|
25
|
+
rescue *rescuable_exceptions
|
37
26
|
raise DatabaseExists, "The database #{environmentify(database)} already exists."
|
38
27
|
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# Separate Adapter for Postgresql when using schemas
|
42
|
-
class JDBCPostgresqlSchemaAdapter < AbstractJDBCAdapter
|
43
|
-
|
44
|
-
# Drop the database schema
|
45
|
-
#
|
46
|
-
# @param {String} database Database (schema) to drop
|
47
|
-
#
|
48
|
-
def drop(database)
|
49
|
-
Apartment.connection.execute(%{DROP SCHEMA "#{database}" CASCADE})
|
50
|
-
|
51
|
-
rescue ActiveRecord::StatementInvalid, ActiveRecord::JDBCError
|
52
|
-
raise SchemaNotFound, "The schema #{database.inspect} cannot be found."
|
53
|
-
end
|
54
28
|
|
55
|
-
#
|
56
|
-
# Set the table_name to always use the default namespace for excluded models
|
29
|
+
# Return a new config that is multi-tenanted
|
57
30
|
#
|
58
|
-
def
|
59
|
-
|
60
|
-
|
61
|
-
# actual object references. This way when we contantize, we always get the proper class reference
|
62
|
-
if excluded_model.is_a? Class
|
63
|
-
warn "[Deprecation Warning] Passing class references to excluded models is now deprecated, please use a string instead"
|
64
|
-
excluded_model = excluded_model.name
|
65
|
-
end
|
66
|
-
|
67
|
-
excluded_model.constantize.tap do |klass|
|
68
|
-
# some models (such as delayed_job) seem to load and cache their column names before this,
|
69
|
-
# so would never get the default prefix, so reset first
|
70
|
-
klass.reset_column_information
|
71
|
-
|
72
|
-
# Ensure that if a schema *was* set, we override
|
73
|
-
table_name = klass.table_name.split('.', 2).last
|
74
|
-
|
75
|
-
# Not sure why, but Delayed::Job somehow ignores table_name_prefix... so we'll just manually set table name instead
|
76
|
-
klass.table_name = "#{Apartment.default_schema}.#{table_name}"
|
77
|
-
end
|
31
|
+
def multi_tenantify(database)
|
32
|
+
@config.clone.tap do |config|
|
33
|
+
config[:url] = "#{config[:url].gsub(/(\S+)\/.+$/, '\1')}/#{environmentify(database)}"
|
78
34
|
end
|
79
35
|
end
|
80
36
|
|
81
|
-
|
82
|
-
#
|
83
|
-
# @return {String} default schema search path
|
84
|
-
#
|
85
|
-
def reset
|
86
|
-
@current_database = Apartment.default_schema
|
87
|
-
Apartment.connection.schema_search_path = full_search_path
|
88
|
-
end
|
37
|
+
private
|
89
38
|
|
90
|
-
def
|
91
|
-
|
39
|
+
def rescue_from
|
40
|
+
ActiveRecord::JDBCError
|
92
41
|
end
|
42
|
+
end
|
93
43
|
|
94
|
-
|
44
|
+
# Separate Adapter for Postgresql when using schemas
|
45
|
+
class JDBCPostgresqlSchemaAdapter < PostgresqlSchemaAdapter
|
95
46
|
|
96
47
|
# Set schema search path to new schema
|
97
48
|
#
|
98
49
|
def connect_to_new(database = nil)
|
99
50
|
return reset if database.nil?
|
51
|
+
raise ActiveRecord::StatementInvalid.new unless Apartment.connection.all_schemas.include? database.to_s
|
100
52
|
|
101
53
|
@current_database = database.to_s
|
102
54
|
Apartment.connection.schema_search_path = full_search_path
|
@@ -105,22 +57,10 @@ module Apartment
|
|
105
57
|
raise SchemaNotFound, "One of the following schema(s) is invalid: #{full_search_path}"
|
106
58
|
end
|
107
59
|
|
108
|
-
|
109
|
-
#
|
110
|
-
def create_database(database)
|
111
|
-
Apartment.connection.execute(%{CREATE SCHEMA "#{database}"})
|
60
|
+
private
|
112
61
|
|
113
|
-
|
114
|
-
|
115
|
-
end
|
116
|
-
|
117
|
-
private
|
118
|
-
|
119
|
-
# Generate the final search path to set including persistent_schemas
|
120
|
-
#
|
121
|
-
def full_search_path
|
122
|
-
persistent_schemas = Apartment.persistent_schemas.join(', ')
|
123
|
-
@current_database.to_s + (persistent_schemas.empty? ? "" : ", #{persistent_schemas}")
|
62
|
+
def rescue_from
|
63
|
+
ActiveRecord::JDBCError
|
124
64
|
end
|
125
65
|
end
|
126
66
|
end
|
@@ -14,20 +14,11 @@ module Apartment
|
|
14
14
|
# Default adapter when not using Postgresql Schemas
|
15
15
|
class PostgresqlAdapter < AbstractAdapter
|
16
16
|
|
17
|
-
|
17
|
+
private
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
# Catch specific adapter errors here
|
22
|
-
#
|
23
|
-
# @param {String} database Database name
|
24
|
-
#
|
25
|
-
def connect_to_new(database)
|
26
|
-
super
|
27
|
-
rescue PGError
|
28
|
-
raise DatabaseNotFound, "Cannot find database #{environmentify(database)}"
|
19
|
+
def rescue_from
|
20
|
+
PGError
|
29
21
|
end
|
30
|
-
|
31
22
|
end
|
32
23
|
|
33
24
|
# Separate Adapter for Postgresql when using schemas
|
@@ -40,7 +31,7 @@ module Apartment
|
|
40
31
|
def drop(database)
|
41
32
|
Apartment.connection.execute(%{DROP SCHEMA "#{database}" CASCADE})
|
42
33
|
|
43
|
-
rescue
|
34
|
+
rescue *rescuable_exceptions
|
44
35
|
raise SchemaNotFound, "The schema #{database.inspect} cannot be found."
|
45
36
|
end
|
46
37
|
|
@@ -49,13 +40,6 @@ module Apartment
|
|
49
40
|
#
|
50
41
|
def process_excluded_models
|
51
42
|
Apartment.excluded_models.each do |excluded_model|
|
52
|
-
# Note that due to rails reloading, we now take string references to classes rather than
|
53
|
-
# actual object references. This way when we contantize, we always get the proper class reference
|
54
|
-
if excluded_model.is_a? Class
|
55
|
-
warn "[Deprecation Warning] Passing class references to excluded models is now deprecated, please use a string instead"
|
56
|
-
excluded_model = excluded_model.name
|
57
|
-
end
|
58
|
-
|
59
43
|
excluded_model.constantize.tap do |klass|
|
60
44
|
# some models (such as delayed_job) seem to load and cache their column names before this,
|
61
45
|
# so would never get the default prefix, so reset first
|
@@ -89,11 +73,12 @@ module Apartment
|
|
89
73
|
#
|
90
74
|
def connect_to_new(database = nil)
|
91
75
|
return reset if database.nil?
|
76
|
+
raise ActiveRecord::StatementInvalid.new unless Apartment.connection.schema_exists? database
|
92
77
|
|
93
78
|
@current_database = database.to_s
|
94
79
|
Apartment.connection.schema_search_path = full_search_path
|
95
80
|
|
96
|
-
rescue
|
81
|
+
rescue *rescuable_exceptions
|
97
82
|
raise SchemaNotFound, "One of the following schema(s) is invalid: #{full_search_path}"
|
98
83
|
end
|
99
84
|
|
@@ -102,7 +87,7 @@ module Apartment
|
|
102
87
|
def create_database(database)
|
103
88
|
Apartment.connection.execute(%{CREATE SCHEMA "#{database}"})
|
104
89
|
|
105
|
-
rescue
|
90
|
+
rescue *rescuable_exceptions
|
106
91
|
raise SchemaExists, "The schema #{database} already exists."
|
107
92
|
end
|
108
93
|
|
@@ -116,4 +101,4 @@ module Apartment
|
|
116
101
|
end
|
117
102
|
end
|
118
103
|
end
|
119
|
-
end
|
104
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Apartment
|
2
|
+
module Database
|
3
|
+
def self.sqlite3_adapter(config)
|
4
|
+
Adapters::Sqlite3Adapter.new(config)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
module Adapters
|
9
|
+
class Sqlite3Adapter < AbstractAdapter
|
10
|
+
def initialize(config)
|
11
|
+
@default_dir = File.expand_path(File.dirname(config[:database]))
|
12
|
+
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def drop(database)
|
17
|
+
raise DatabaseNotFound,
|
18
|
+
"The database #{environmentify(database)} cannot be found." unless File.exists?(database_file(database))
|
19
|
+
|
20
|
+
File.delete(database_file(database))
|
21
|
+
end
|
22
|
+
|
23
|
+
def current_database
|
24
|
+
File.basename(Apartment.connection.instance_variable_get(:@config)[:database], '.sqlite3')
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def connect_to_new(database)
|
30
|
+
raise DatabaseNotFound,
|
31
|
+
"The database #{environmentify(database)} cannot be found." unless File.exists?(database_file(database))
|
32
|
+
|
33
|
+
super database_file(database)
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_database(database)
|
37
|
+
raise DatabaseExists,
|
38
|
+
"The database #{environmentify(database)} already exists." if File.exists?(database_file(database))
|
39
|
+
|
40
|
+
f = File.new(database_file(database), File::CREAT)
|
41
|
+
f.close
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def database_file(database)
|
47
|
+
"#{@default_dir}/#{database}.sqlite3"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,14 +1,15 @@
|
|
1
1
|
module Apartment
|
2
2
|
module Elevators
|
3
|
-
# Provides a rack based db switching solution based on
|
4
|
-
#
|
3
|
+
# Provides a rack based db switching solution based on the first subdomain
|
4
|
+
# of a given domain name.
|
5
|
+
# eg:
|
6
|
+
# - example1.domain.com => example1
|
7
|
+
# - example2.something.domain.com => example2
|
5
8
|
class FirstSubdomain < Subdomain
|
6
9
|
|
7
10
|
def parse_database_name(request)
|
8
|
-
|
9
|
-
subdomain && subdomain.match(/(\w+)(\.\w+)?/)[1]
|
11
|
+
super.split('.')[0]
|
10
12
|
end
|
11
|
-
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
data/lib/apartment/version.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'apartment/adapters/sqlite3_adapter'
|
3
|
+
|
4
|
+
describe Apartment::Adapters::Sqlite3Adapter do
|
5
|
+
unless defined?(JRUBY_VERSION)
|
6
|
+
|
7
|
+
let(:config){ Apartment::Test.config['connections']['sqlite'].symbolize_keys }
|
8
|
+
subject{ Apartment::Database.sqlite3_adapter config }
|
9
|
+
|
10
|
+
context "using connections" do
|
11
|
+
def database_names
|
12
|
+
db_dir = File.expand_path("../../dummy/db", __FILE__)
|
13
|
+
Dir.glob("#{db_dir}/*.sqlite3").map { |file| File.basename(file, '.sqlite3') }
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:default_database) do
|
17
|
+
subject.process { File.basename(Apartment::Test.config['connections']['sqlite']['database'], '.sqlite3') }
|
18
|
+
end
|
19
|
+
|
20
|
+
it_should_behave_like "a generic apartment adapter"
|
21
|
+
it_should_behave_like "a connection based apartment adapter"
|
22
|
+
|
23
|
+
after(:all) do
|
24
|
+
File.delete(Apartment::Test.config['connections']['sqlite']['database'])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -43,18 +43,28 @@ describe Apartment::Delayed do
|
|
43
43
|
user.database.should == database
|
44
44
|
end
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
context 'when there are defined callbacks' do
|
47
|
+
before do
|
48
|
+
User.class_eval do
|
49
|
+
after_find :set_name
|
50
|
+
|
51
|
+
def set_name
|
52
|
+
self.name = "Some Name"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
49
56
|
|
50
|
-
|
51
|
-
|
57
|
+
after do
|
58
|
+
User.class_eval do
|
59
|
+
reset_callbacks :find
|
52
60
|
end
|
53
61
|
end
|
54
62
|
|
55
|
-
|
56
|
-
|
57
|
-
|
63
|
+
it "should not overwrite any previous after_initialize declarations" do
|
64
|
+
user = User.first
|
65
|
+
user.database.should == database
|
66
|
+
user.name.should == "Some Name"
|
67
|
+
end
|
58
68
|
end
|
59
69
|
|
60
70
|
it "should set the db on a new record before it saves" do
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'query caching' do
|
4
|
+
before do
|
5
|
+
Apartment.configure do |config|
|
6
|
+
config.excluded_models = ["Company"]
|
7
|
+
config.database_names = lambda{ Company.scoped.collect(&:database) }
|
8
|
+
end
|
9
|
+
|
10
|
+
db_names.each do |db_name|
|
11
|
+
Apartment::Database.create(db_name)
|
12
|
+
Company.create :database => db_name
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
after do
|
17
|
+
db_names.each{ |db| Apartment::Database.drop(db) }
|
18
|
+
Company.delete_all
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:db_names) { 2.times.map{ Apartment::Test.next_db } }
|
22
|
+
|
23
|
+
it 'clears the ActiveRecord::QueryCache after switching databases' do
|
24
|
+
db_names.each do |db_name|
|
25
|
+
Apartment::Database.switch db_name
|
26
|
+
User.create! name: db_name
|
27
|
+
end
|
28
|
+
|
29
|
+
ActiveRecord::Base.connection.enable_query_cache!
|
30
|
+
|
31
|
+
Apartment::Database.switch db_names.first
|
32
|
+
User.find_by_name(db_names.first).name.should == db_names.first
|
33
|
+
|
34
|
+
Apartment::Database.switch db_names.last
|
35
|
+
User.find_by_name(db_names.first).should be_nil
|
36
|
+
end
|
37
|
+
end
|
metadata
CHANGED
@@ -1,50 +1,51 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: apartment
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
4
|
+
version: 0.21.1
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Ryan Brunner
|
9
9
|
- Brad Robertson
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-05-31 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
17
|
-
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
18
19
|
requirements:
|
19
|
-
- -
|
20
|
+
- - ! '>='
|
20
21
|
- !ruby/object:Gem::Version
|
21
22
|
version: 3.1.2
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
26
|
none: false
|
23
|
-
requirement: !ruby/object:Gem::Requirement
|
24
27
|
requirements:
|
25
|
-
- -
|
28
|
+
- - ! '>='
|
26
29
|
- !ruby/object:Gem::Version
|
27
30
|
version: 3.1.2
|
28
|
-
none: false
|
29
|
-
prerelease: false
|
30
|
-
type: :runtime
|
31
31
|
- !ruby/object:Gem::Dependency
|
32
32
|
name: rack
|
33
|
-
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
34
35
|
requirements:
|
35
|
-
- -
|
36
|
+
- - ! '>='
|
36
37
|
- !ruby/object:Gem::Version
|
37
38
|
version: 1.3.6
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
42
|
none: false
|
39
|
-
requirement: !ruby/object:Gem::Requirement
|
40
43
|
requirements:
|
41
|
-
- -
|
44
|
+
- - ! '>='
|
42
45
|
- !ruby/object:Gem::Version
|
43
46
|
version: 1.3.6
|
44
|
-
|
45
|
-
|
46
|
-
type: :runtime
|
47
|
-
description: Apartment allows Rack applications to deal with database multitenancy through ActiveRecord
|
47
|
+
description: Apartment allows Rack applications to deal with database multitenancy
|
48
|
+
through ActiveRecord
|
48
49
|
email:
|
49
50
|
- ryan@influitive.com
|
50
51
|
- brad@influitive.com
|
@@ -52,12 +53,12 @@ executables: []
|
|
52
53
|
extensions: []
|
53
54
|
extra_rdoc_files: []
|
54
55
|
files:
|
55
|
-
-
|
56
|
-
-
|
57
|
-
-
|
58
|
-
-
|
59
|
-
-
|
60
|
-
-
|
56
|
+
- .gitignore
|
57
|
+
- .pryrc
|
58
|
+
- .rspec
|
59
|
+
- .rvmrc
|
60
|
+
- .travis.yml
|
61
|
+
- .vagrant
|
61
62
|
- Cheffile
|
62
63
|
- Cheffile.lock
|
63
64
|
- Gemfile
|
@@ -75,6 +76,7 @@ files:
|
|
75
76
|
- lib/apartment/adapters/mysql2_adapter.rb
|
76
77
|
- lib/apartment/adapters/postgis_adapter.rb
|
77
78
|
- lib/apartment/adapters/postgresql_adapter.rb
|
79
|
+
- lib/apartment/adapters/sqlite3_adapter.rb
|
78
80
|
- lib/apartment/console.rb
|
79
81
|
- lib/apartment/database.rb
|
80
82
|
- lib/apartment/delayed_job/enqueue.rb
|
@@ -100,6 +102,7 @@ files:
|
|
100
102
|
- spec/adapters/jdbc_postgresql_adapter_spec.rb
|
101
103
|
- spec/adapters/mysql2_adapter_spec.rb
|
102
104
|
- spec/adapters/postgresql_adapter_spec.rb
|
105
|
+
- spec/adapters/sqlite3_adapter_spec.rb
|
103
106
|
- spec/apartment_spec.rb
|
104
107
|
- spec/config/database.yml.sample
|
105
108
|
- spec/database_spec.rb
|
@@ -148,6 +151,7 @@ files:
|
|
148
151
|
- spec/integration/middleware/first_subdomain_elevator_spec.rb
|
149
152
|
- spec/integration/middleware/generic_elevator_spec.rb
|
150
153
|
- spec/integration/middleware/subdomain_elevator_spec.rb
|
154
|
+
- spec/integration/query_caching_spec.rb
|
151
155
|
- spec/spec_helper.rb
|
152
156
|
- spec/support/apartment_helpers.rb
|
153
157
|
- spec/support/capybara_sessions.rb
|
@@ -163,34 +167,32 @@ files:
|
|
163
167
|
homepage: https://github.com/influitive/apartment
|
164
168
|
licenses:
|
165
169
|
- MIT
|
166
|
-
post_install_message:
|
170
|
+
post_install_message:
|
167
171
|
rdoc_options: []
|
168
172
|
require_paths:
|
169
173
|
- lib
|
170
174
|
required_ruby_version: !ruby/object:Gem::Requirement
|
175
|
+
none: false
|
171
176
|
requirements:
|
172
|
-
- -
|
177
|
+
- - ! '>='
|
173
178
|
- !ruby/object:Gem::Version
|
179
|
+
version: '0'
|
174
180
|
segments:
|
175
181
|
- 0
|
176
|
-
hash:
|
177
|
-
version: !binary |-
|
178
|
-
MA==
|
179
|
-
none: false
|
182
|
+
hash: 2789245529283699970
|
180
183
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
|
+
none: false
|
181
185
|
requirements:
|
182
|
-
- -
|
186
|
+
- - ! '>='
|
183
187
|
- !ruby/object:Gem::Version
|
188
|
+
version: '0'
|
184
189
|
segments:
|
185
190
|
- 0
|
186
|
-
hash:
|
187
|
-
version: !binary |-
|
188
|
-
MA==
|
189
|
-
none: false
|
191
|
+
hash: 2789245529283699970
|
190
192
|
requirements: []
|
191
|
-
rubyforge_project:
|
192
|
-
rubygems_version: 1.8.
|
193
|
-
signing_key:
|
193
|
+
rubyforge_project:
|
194
|
+
rubygems_version: 1.8.25
|
195
|
+
signing_key:
|
194
196
|
specification_version: 3
|
195
197
|
summary: A Ruby gem for managing database multitenancy
|
196
198
|
test_files:
|
@@ -198,6 +200,7 @@ test_files:
|
|
198
200
|
- spec/adapters/jdbc_postgresql_adapter_spec.rb
|
199
201
|
- spec/adapters/mysql2_adapter_spec.rb
|
200
202
|
- spec/adapters/postgresql_adapter_spec.rb
|
203
|
+
- spec/adapters/sqlite3_adapter_spec.rb
|
201
204
|
- spec/apartment_spec.rb
|
202
205
|
- spec/config/database.yml.sample
|
203
206
|
- spec/database_spec.rb
|
@@ -246,6 +249,7 @@ test_files:
|
|
246
249
|
- spec/integration/middleware/first_subdomain_elevator_spec.rb
|
247
250
|
- spec/integration/middleware/generic_elevator_spec.rb
|
248
251
|
- spec/integration/middleware/subdomain_elevator_spec.rb
|
252
|
+
- spec/integration/query_caching_spec.rb
|
249
253
|
- spec/spec_helper.rb
|
250
254
|
- spec/support/apartment_helpers.rb
|
251
255
|
- spec/support/capybara_sessions.rb
|