apartment 0.1.3 → 0.5.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.
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +5 -12
- data/HISTORY.md +31 -0
- data/{README.markdown → README.md} +39 -21
- data/Rakefile +44 -47
- data/apartment.gemspec +19 -58
- data/lib/apartment.rb +57 -6
- data/lib/apartment/adapters/abstract_adapter.rb +106 -0
- data/lib/apartment/adapters/mysql_adapter.rb +11 -0
- data/lib/apartment/adapters/postgresql_adapter.rb +55 -0
- data/lib/apartment/database.rb +58 -74
- data/lib/apartment/elevators/subdomain.rb +27 -0
- data/lib/apartment/migrator.rb +23 -0
- data/lib/apartment/railtie.rb +1 -2
- data/lib/apartment/version.rb +3 -0
- data/lib/tasks/apartment.rake +36 -0
- data/spec/apartment_spec.rb +7 -0
- data/spec/config/database.yml +10 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +6 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/company.rb +3 -0
- data/spec/dummy/app/models/user.rb +3 -0
- data/spec/dummy/app/views/application/index.html.erb +1 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +47 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +8 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +26 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +35 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/db/migrate/20110613152810_create_dummy_models.rb +20 -0
- data/spec/dummy/db/schema.rb +26 -0
- data/spec/dummy/db/seeds.rb +8 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/{lib/apartment/associations/multi_tenant_association.rb → spec/dummy/public/favicon.ico} +0 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/integration/adapters/postgresql_integration_spec.rb +73 -0
- data/spec/integration/apartment_rake_integration_spec.rb +62 -0
- data/spec/integration/database_integration_spec.rb +107 -0
- data/spec/integration/middleware/subdomain_elevator_spec.rb +63 -0
- data/spec/integration/setup_spec.rb +8 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/support/apartment_helpers.rb +24 -0
- data/spec/support/capybara_sessions.rb +15 -0
- data/spec/support/config.rb +11 -0
- data/spec/support/migrate.rb +9 -0
- data/spec/tasks/apartment_rake_spec.rb +110 -0
- data/spec/unit/config_spec.rb +84 -0
- data/spec/unit/middleware/subdomain_elevator_spec.rb +20 -0
- data/spec/unit/migrator_spec.rb +87 -0
- metadata +112 -62
- data/.bundle/config +0 -2
- data/.project +0 -11
- data/Gemfile.lock +0 -22
- data/VERSION +0 -1
- data/lib/apartment/config.rb +0 -10
- data/lib/apartment/config/default_config.yml +0 -17
- data/lib/tasks/multi_tenant_migrate.rake +0 -14
- data/pkg/apartment-0.1.3.gem +0 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm 1.9.2@apartment
|
data/Gemfile
CHANGED
@@ -1,15 +1,8 @@
|
|
1
1
|
source "http://rubygems.org"
|
2
|
-
# Add dependencies required to use your gem here.
|
3
|
-
# Example:
|
4
2
|
|
5
|
-
|
3
|
+
# Uses patched version of postgresql adapter to enable apartment usage.
|
4
|
+
# Current postgresql adapter in rails doesn't properly support the use of postgresql schemas
|
5
|
+
# Pull request sent => https://github.com/rails/rails/pull/1604
|
6
|
+
gem 'rails', '3.0.8', :git => 'git://github.com/bradrobertson/rails', :branch => '3-0-stable'
|
6
7
|
|
7
|
-
|
8
|
-
# Add dependencies to develop your gem here.
|
9
|
-
# Include everything needed to run rake, tests, features, etc.
|
10
|
-
group :development do
|
11
|
-
gem "shoulda", ">= 0"
|
12
|
-
gem "bundler", "~> 1.0.0"
|
13
|
-
gem "jeweler", "~> 1.5.1"
|
14
|
-
gem "rcov", ">= 0"
|
15
|
-
end
|
8
|
+
gemspec
|
data/HISTORY.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# 0.5.0
|
2
|
+
* June 20, 2011
|
3
|
+
|
4
|
+
- Added the concept of an "Elevator", a rack based strategy for db switching
|
5
|
+
- Added the Subdomain Elevator middleware to enabled db switching based on subdomain
|
6
|
+
|
7
|
+
# 0.4.0
|
8
|
+
* June 14, 2011
|
9
|
+
|
10
|
+
- Added `configure` method on Apartment instead of using yml file, allows for dynamic setting of db names to migrate for rake task
|
11
|
+
- Added `seed_after_create` config option to import seed data to new db on create
|
12
|
+
|
13
|
+
# 0.3.0
|
14
|
+
* June 10, 2011
|
15
|
+
|
16
|
+
- Added full support for database migration
|
17
|
+
- Added in method to establish new connection for excluded models on startup rather than on each switch
|
18
|
+
|
19
|
+
# 0.2.0
|
20
|
+
* June 6, 2011 *
|
21
|
+
|
22
|
+
- Refactor to use more rails/active_support functionality
|
23
|
+
- Refactor config to lazily load apartment.yml if exists
|
24
|
+
- Remove OStruct and just use hashes for fetching methods
|
25
|
+
- Added schema load on create instead of migrating from scratch
|
26
|
+
|
27
|
+
# 0.1.3
|
28
|
+
* March 30, 2011 *
|
29
|
+
|
30
|
+
- Original pass from Ryan
|
31
|
+
|
@@ -51,7 +51,7 @@ would not allow a full new database to be created.
|
|
51
51
|
|
52
52
|
To switch databases using Apartment, use the following command:
|
53
53
|
|
54
|
-
|
54
|
+
Apartment::Database.switch('database_name')
|
55
55
|
|
56
56
|
When switch is called, all requests coming to ActiveRecord will be routed to the database
|
57
57
|
you specify (with the exception of excluded models, see below). To return to the 'root'
|
@@ -59,32 +59,50 @@ database, call switch with no arguments.
|
|
59
59
|
|
60
60
|
### Switching Databases per request
|
61
61
|
|
62
|
-
You can have Apartment route to the appropriate database
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
62
|
+
You can have Apartment route to the appropriate database by adding some Rack middleware.
|
63
|
+
Apartment can support many different "Elevators" that can take care of this routing to your data.
|
64
|
+
In house, we use the subdomain elevator, which analyzes the subdomain of the request and switches
|
65
|
+
to a database schema of the same name. It can be used like so:
|
66
|
+
|
67
|
+
# application.rb
|
68
|
+
module My Application
|
69
|
+
class Application < Rails::Application
|
70
|
+
|
71
|
+
config.middleware.use 'Apartment::Elevators::Subdomain'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
73
75
|
### Excluding models
|
74
76
|
|
75
|
-
If you have some models that should always access the 'root' database, you can specify this
|
76
|
-
|
77
|
-
directory of your Rails application. To exclude certain models, do the following:
|
77
|
+
If you have some models that should always access the 'root' database, you can specify this by configuring
|
78
|
+
Apartment using `Apartment.configure`. This will yield a config object for you. You can set excluded models like so:
|
78
79
|
|
79
|
-
|
80
|
+
Apartment.configure do |config|
|
81
|
+
config.excluded_models = [User, Company] # these models will not be multi-tenanted, but remain in the global (public) namespace
|
82
|
+
end
|
80
83
|
|
81
84
|
### Managing Migrations
|
82
85
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
86
|
+
In order to migrate all of your databases (or posgresql schemas) you need to provide a list
|
87
|
+
of dbs to Apartment. You can make this dynamic by providing a Proc object to be called on migrations.
|
88
|
+
This object should yield an array of string representing each database name. Example:
|
89
|
+
|
90
|
+
# Dynamically get database names to migrate
|
91
|
+
Apartment.configure do |config|
|
92
|
+
config.database_names = lambda{ Company.all.collect(&:database_name) }
|
93
|
+
end
|
94
|
+
|
95
|
+
# Use a static list of database names for migrate
|
96
|
+
Apartment.configure do |config|
|
97
|
+
config.database_names = ['db1', 'db2']
|
98
|
+
end
|
99
|
+
|
100
|
+
You can then migration your databases using the rake task:
|
101
|
+
|
102
|
+
rake apartment:migrate
|
103
|
+
|
104
|
+
This basically invokes `Apartment::Database.migrate(#{db_name})` for each database name supplied
|
105
|
+
from `Apartment.database_names`
|
88
106
|
|
89
107
|
## TODO
|
90
108
|
|
data/Rakefile
CHANGED
@@ -1,54 +1,51 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
|
4
|
-
Bundler.setup(:default, :development)
|
5
|
-
rescue Bundler::BundlerError => e
|
6
|
-
$stderr.puts e.message
|
7
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
-
exit e.status_code
|
9
|
-
end
|
10
|
-
require 'rake'
|
1
|
+
require 'bundler' rescue 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
2
|
+
Bundler.setup
|
3
|
+
Bundler::GemHelper.install_tasks
|
11
4
|
|
12
|
-
require
|
13
|
-
|
14
|
-
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
-
gem.name = "apartment"
|
16
|
-
gem.homepage = "http://github.com/ryanbrunner/apartment"
|
17
|
-
gem.license = "MIT"
|
18
|
-
gem.summary = %Q{A Ruby gem for managing multitenancy in Rails applications}
|
19
|
-
gem.description = %Q{Apartment allows Rails applications to deal with
|
20
|
-
multitenancy.}
|
21
|
-
gem.email = "ryan@ryanbrunner.com"
|
22
|
-
gem.authors = ["Ryan Brunner"]
|
23
|
-
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
24
|
-
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
25
|
-
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
26
|
-
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
27
|
-
end
|
28
|
-
Jeweler::RubygemsDotOrgTasks.new
|
5
|
+
require "rspec"
|
6
|
+
require "rspec/core/rake_task"
|
29
7
|
|
30
|
-
|
31
|
-
|
32
|
-
test.libs << 'lib' << 'test'
|
33
|
-
test.pattern = 'test/**/test_*.rb'
|
34
|
-
test.verbose = true
|
8
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
9
|
+
spec.pattern = "spec/**/*_spec.rb"
|
35
10
|
end
|
36
11
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
12
|
+
namespace :spec do
|
13
|
+
|
14
|
+
[:tasks, :unit, :integration].each do |type|
|
15
|
+
RSpec::Core::RakeTask.new(type) do |spec|
|
16
|
+
spec.pattern = "spec/#{type}/**/*_spec.rb"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
namespace :unit do
|
21
|
+
RSpec::Core::RakeTask.new(:adapters) do |spec|
|
22
|
+
spec.pattern = "spec/unit/adapters/**/*_spec.rb"
|
23
|
+
end
|
24
|
+
end
|
43
25
|
|
44
|
-
|
26
|
+
end
|
45
27
|
|
46
|
-
|
47
|
-
Rake::RDocTask.new do |rdoc|
|
48
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
28
|
+
task :default => :spec
|
49
29
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
30
|
+
namespace :postgres do
|
31
|
+
require 'active_record'
|
32
|
+
require "#{File.join(File.dirname(__FILE__), 'spec', 'support', 'config')}"
|
33
|
+
|
34
|
+
desc 'Build the PostgreSQL test databases'
|
35
|
+
task :build_db do
|
36
|
+
%x{ createdb -E UTF8 #{config['database']} } rescue "test db already exists"
|
37
|
+
ActiveRecord::Base.establish_connection config
|
38
|
+
load 'spec/dummy/db/schema.rb'
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "drop the PostgreSQL test database"
|
42
|
+
task :drop_db do
|
43
|
+
puts "dropping database #{config['database']}"
|
44
|
+
%x{ dropdb #{config['database']} }
|
45
|
+
end
|
46
|
+
|
47
|
+
def config
|
48
|
+
Apartment::Test.config['connections']['postgresql']
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
data/apartment.gemspec
CHANGED
@@ -1,68 +1,29 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
$: << File.expand_path("../lib", __FILE__)
|
3
|
+
require "apartment/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |s|
|
7
6
|
s.name = %q{apartment}
|
8
|
-
s.version =
|
7
|
+
s.version = Apartment::VERSION
|
9
8
|
|
10
|
-
s.
|
11
|
-
s.
|
12
|
-
s.
|
13
|
-
s.description = %q{Apartment allows Rails applications to deal with
|
14
|
-
|
15
|
-
s.
|
16
|
-
s.
|
17
|
-
|
18
|
-
]
|
19
|
-
s.files = [
|
20
|
-
".bundle/config",
|
21
|
-
".project",
|
22
|
-
"Gemfile",
|
23
|
-
"Gemfile.lock",
|
24
|
-
"README.markdown",
|
25
|
-
"Rakefile",
|
26
|
-
"VERSION",
|
27
|
-
"apartment.gemspec",
|
28
|
-
"lib/apartment.rb",
|
29
|
-
"lib/apartment/associations/multi_tenant_association.rb",
|
30
|
-
"lib/apartment/config.rb",
|
31
|
-
"lib/apartment/config/default_config.yml",
|
32
|
-
"lib/apartment/database.rb",
|
33
|
-
"lib/apartment/railtie.rb",
|
34
|
-
"lib/tasks/multi_tenant_migrate.rake",
|
35
|
-
"pkg/apartment-0.1.3.gem"
|
36
|
-
]
|
9
|
+
s.authors = ["Ryan Brunner", "Brad Robertson"]
|
10
|
+
s.date = %q{2011-04-18}
|
11
|
+
s.summary = %q{A Ruby gem for managing database multitenancy in Rails applications}
|
12
|
+
s.description = %q{Apartment allows Rails applications to deal with database multitenancy}
|
13
|
+
s.email = %w{ryan@ryanbrunner.com bradleyrobertson@gmail.com}
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
16
|
+
|
37
17
|
s.homepage = %q{http://github.com/ryanbrunner/apartment}
|
38
18
|
s.licenses = ["MIT"]
|
39
19
|
s.require_paths = ["lib"]
|
40
20
|
s.rubygems_version = %q{1.3.7}
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
50
|
-
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
51
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
|
52
|
-
s.add_development_dependency(%q<rcov>, [">= 0"])
|
53
|
-
else
|
54
|
-
s.add_dependency(%q<activesupport>, [">= 3.0.5"])
|
55
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
56
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
57
|
-
s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
|
58
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
59
|
-
end
|
60
|
-
else
|
61
|
-
s.add_dependency(%q<activesupport>, [">= 3.0.5"])
|
62
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
63
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
64
|
-
s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
|
65
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
66
|
-
end
|
21
|
+
|
22
|
+
s.add_dependency 'rails', '~> 3.0.8'
|
23
|
+
s.add_development_dependency 'sqlite3'
|
24
|
+
s.add_development_dependency 'rspec', '~> 2.6.0'
|
25
|
+
s.add_development_dependency 'rspec-rails', '~> 2.6.1'
|
26
|
+
s.add_development_dependency 'capybara', '1.0.0'
|
27
|
+
s.add_development_dependency 'pg', '~> 0.11.0'
|
28
|
+
s.add_development_dependency "silent-postgres", "~> 0.0.8"
|
67
29
|
end
|
68
|
-
|
data/lib/apartment.rb
CHANGED
@@ -1,11 +1,62 @@
|
|
1
|
+
require 'apartment/railtie'
|
1
2
|
|
2
3
|
module Apartment
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_accessor :use_postgres_schemas, :seed_after_create
|
7
|
+
attr_writer :database_names, :excluded_models
|
8
|
+
|
9
|
+
# configure apartment with available options
|
10
|
+
def configure
|
11
|
+
yield self if block_given?
|
12
|
+
Database.init
|
13
|
+
end
|
14
|
+
|
15
|
+
# Be careful not to use `return` here so both Proc and lambda can be used without breaking
|
16
|
+
def database_names
|
17
|
+
if @database_names.respond_to?(:call)
|
18
|
+
@database_names.call
|
19
|
+
else
|
20
|
+
@database_names
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Default to none
|
25
|
+
def excluded_models
|
26
|
+
@excluded_models || []
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
autoload :Database, 'apartment/database'
|
32
|
+
autoload :Migrator, 'apartment/migrator'
|
33
|
+
|
34
|
+
module Adapters
|
35
|
+
autoload :AbstractAdapter, 'apartment/adapters/abstract_adapter'
|
36
|
+
# Specific adapters will be loaded dynamically based on adapter in config
|
37
|
+
end
|
38
|
+
|
39
|
+
module Elevators
|
40
|
+
autoload :Subdomain, 'apartment/elevators/subdomain'
|
9
41
|
end
|
42
|
+
|
43
|
+
# Exceptions
|
44
|
+
class ApartmentError < StandardError; end
|
45
|
+
|
46
|
+
# Raised when apartment cannot find the adapter specified in <tt>config/database.yml</tt>
|
47
|
+
class AdapterNotFound < ApartmentError; end
|
48
|
+
|
49
|
+
# Raised when database cannot find the specified schema
|
50
|
+
class SchemaNotFound < ApartmentError; end
|
51
|
+
|
52
|
+
# Raised when trying to create a schema that already exists
|
53
|
+
class SchemaExists < ApartmentError; end
|
54
|
+
|
10
55
|
end
|
11
56
|
|
57
|
+
Apartment.configure do |config|
|
58
|
+
config.excluded_models = []
|
59
|
+
config.use_postgres_schemas = true
|
60
|
+
config.database_names = []
|
61
|
+
config.seed_after_create = false
|
62
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module Apartment
|
4
|
+
|
5
|
+
module Adapters
|
6
|
+
|
7
|
+
class AbstractAdapter
|
8
|
+
|
9
|
+
# @constructor
|
10
|
+
# @param {Hash} config Database config
|
11
|
+
# @param {Hash} defaults Some default options
|
12
|
+
#
|
13
|
+
def initialize(config, defaults)
|
14
|
+
@config = config
|
15
|
+
@defaults = defaults
|
16
|
+
end
|
17
|
+
|
18
|
+
# Connect to db or schema, do stuff, reset
|
19
|
+
#
|
20
|
+
# @param {String} database Database or schema to connect to
|
21
|
+
def connect_and_reset(database)
|
22
|
+
connect_to_new(database)
|
23
|
+
yield if block_given?
|
24
|
+
ensure
|
25
|
+
reset
|
26
|
+
end
|
27
|
+
|
28
|
+
# Create new postgres schema
|
29
|
+
#
|
30
|
+
# @param {String} database Database name
|
31
|
+
def create(database)
|
32
|
+
# TODO create_database unless using_schemas?
|
33
|
+
|
34
|
+
connect_and_reset(database) do
|
35
|
+
import_database_schema
|
36
|
+
|
37
|
+
# Manually init schema migrations table (apparently there were issues with Postgres when this isn't done)
|
38
|
+
ActiveRecord::Base.connection.initialize_schema_migrations_table
|
39
|
+
|
40
|
+
# Seed data if appropriate
|
41
|
+
seed_data if Apartment.seed_after_create
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Reset the base connection
|
46
|
+
def reset
|
47
|
+
ActiveRecord::Base.establish_connection @config
|
48
|
+
end
|
49
|
+
|
50
|
+
# Switch to new connection (or schema if appopriate)
|
51
|
+
def switch(database = nil)
|
52
|
+
# Just connect to default db and return
|
53
|
+
return reset if database.nil?
|
54
|
+
|
55
|
+
connect_to_new(database)
|
56
|
+
end
|
57
|
+
|
58
|
+
protected
|
59
|
+
|
60
|
+
def create_schema
|
61
|
+
# noop
|
62
|
+
end
|
63
|
+
|
64
|
+
def connect_to_new(database)
|
65
|
+
ActiveRecord::Base.establish_connection multi_tenantify(database)
|
66
|
+
end
|
67
|
+
|
68
|
+
def import_database_schema
|
69
|
+
load_or_abort("#{Rails.root}/db/schema.rb")
|
70
|
+
end
|
71
|
+
|
72
|
+
def seed_data
|
73
|
+
load_or_abort("#{Rails.root}/db/seeds.rb")
|
74
|
+
end
|
75
|
+
|
76
|
+
# Return a new config that is multi-tenanted
|
77
|
+
def multi_tenantify(database)
|
78
|
+
@config.clone.tap do |config|
|
79
|
+
config['database'].gsub!(Rails.env.to_s, "#{database}_#{Rails.env}")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Remove all non-alphanumeric characters
|
84
|
+
def sanitize(database)
|
85
|
+
database.gsub(/[\W]/,'')
|
86
|
+
end
|
87
|
+
|
88
|
+
# Whether or not to use postgresql schemas
|
89
|
+
def using_schemas?
|
90
|
+
false
|
91
|
+
end
|
92
|
+
|
93
|
+
def load_or_abort(file)
|
94
|
+
if File.exists?(file)
|
95
|
+
load(file)
|
96
|
+
else
|
97
|
+
abort %{#{file} doesn't exist yet}
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|