apartment 0.1.3 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|