stop vendoring rails multisite
This commit is contained in:
parent
e17978a203
commit
cf52671feb
4
Gemfile
4
Gemfile
|
@ -35,7 +35,9 @@ gem 'barber'
|
|||
gem 'babel-transpiler'
|
||||
|
||||
gem 'message_bus'
|
||||
gem 'rails_multisite', path: 'vendor/gems/rails_multisite'
|
||||
|
||||
# temporary while getting ownership of rails_multisite gem
|
||||
gem 'rails_multisite_discourse', require: 'rails_multisite'
|
||||
|
||||
gem 'fast_xs'
|
||||
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
PATH
|
||||
remote: vendor/gems/rails_multisite
|
||||
specs:
|
||||
rails_multisite (0.0.1)
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
|
@ -304,6 +299,7 @@ GEM
|
|||
loofah (~> 2.0)
|
||||
rails-observers (0.1.2)
|
||||
activemodel (~> 4.0)
|
||||
rails_multisite_discourse (1.0.0)
|
||||
railties (4.2.4)
|
||||
actionpack (= 4.2.4)
|
||||
activesupport (= 4.2.4)
|
||||
|
@ -504,7 +500,7 @@ DEPENDENCIES
|
|||
rack-protection
|
||||
rails (~> 4.2)
|
||||
rails-observers
|
||||
rails_multisite!
|
||||
rails_multisite_discourse
|
||||
rake
|
||||
rb-fsevent
|
||||
rb-inotify (~> 0.9)
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
*.gem
|
||||
*.rbc
|
||||
.bundle
|
||||
.config
|
||||
.yardoc
|
||||
Gemfile.lock
|
||||
InstalledFiles
|
||||
_yardoc
|
||||
coverage
|
||||
doc/
|
||||
lib/bundler/man
|
||||
pkg
|
||||
rdoc
|
||||
spec/reports
|
||||
test/tmp
|
||||
test/version_tmp
|
||||
tmp
|
|
@ -1,14 +0,0 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
group :test do
|
||||
gem 'rails'
|
||||
gem 'rspec'
|
||||
gem 'activerecord'
|
||||
gem 'sqlite3'
|
||||
end
|
||||
|
||||
gem 'guard'
|
||||
gem 'guard-rspec'
|
||||
|
||||
# Specify your gem's dependencies in rails_multisite.gemspec
|
||||
gemspec
|
|
@ -1,9 +0,0 @@
|
|||
# A sample Guardfile
|
||||
# More info at https://github.com/guard/guard#readme
|
||||
|
||||
guard :rspec do
|
||||
watch(%r{^spec/.+_spec\.rb$})
|
||||
watch(%r{^lib/rails_multisite/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
||||
watch('spec/spec_helper.rb') { "spec" }
|
||||
end
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
Copyright (c) 2012 Sam Saffron
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -1,29 +0,0 @@
|
|||
# RailsMultisite
|
||||
|
||||
TODO: Write a gem description
|
||||
|
||||
## Installation
|
||||
|
||||
Add this line to your application's Gemfile:
|
||||
|
||||
gem 'rails_multisite'
|
||||
|
||||
And then execute:
|
||||
|
||||
$ bundle
|
||||
|
||||
Or install it yourself as:
|
||||
|
||||
$ gem install rails_multisite
|
||||
|
||||
## Usage
|
||||
|
||||
TODO: Write usage instructions here
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork it
|
||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
3. Commit your changes (`git commit -am 'Added some feature'`)
|
||||
4. Push to the branch (`git push origin my-new-feature`)
|
||||
5. Create new Pull Request
|
|
@ -1,7 +0,0 @@
|
|||
#!/usr/bin/env rake
|
||||
require "bundler/gem_tasks"
|
||||
require "rspec/core/rake_task"
|
||||
|
||||
RSpec::Core::RakeTask.new(:test) do |spec|
|
||||
spec.pattern = 'spec/*_spec.rb'
|
||||
end
|
|
@ -1,3 +0,0 @@
|
|||
require "rails_multisite/version"
|
||||
require "rails_multisite/railtie"
|
||||
require "rails_multisite/connection_management"
|
|
@ -1,190 +0,0 @@
|
|||
module RailsMultisite
|
||||
class ConnectionManagement
|
||||
CONFIG_FILE = 'config/multisite.yml'
|
||||
DEFAULT = 'default'.freeze
|
||||
|
||||
def self.has_db?(db)
|
||||
return true if db == DEFAULT
|
||||
(defined? @@db_spec_cache) && @@db_spec_cache && @@db_spec_cache[db]
|
||||
end
|
||||
|
||||
def self.rails4?
|
||||
!!(Rails.version =~ /^4/)
|
||||
end
|
||||
|
||||
def self.establish_connection(opts)
|
||||
if opts[:db] == DEFAULT && (!defined?(@@default_spec) || !@@default_spec)
|
||||
# don't do anything .. handled implicitly
|
||||
else
|
||||
spec = connection_spec(opts) || @@default_spec
|
||||
handler = nil
|
||||
if spec != @@default_spec
|
||||
handler = @@connection_handlers[spec]
|
||||
unless handler
|
||||
handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
|
||||
handler.establish_connection(ActiveRecord::Base, spec)
|
||||
@@connection_handlers[spec] = handler
|
||||
end
|
||||
else
|
||||
handler = @@default_connection_handler
|
||||
if !@@established_default
|
||||
handler.establish_connection(ActiveRecord::Base, spec)
|
||||
@@established_default = true
|
||||
end
|
||||
end
|
||||
|
||||
ActiveRecord::Base.connection_handler = handler
|
||||
end
|
||||
end
|
||||
|
||||
def self.with_hostname(hostname)
|
||||
|
||||
unless defined? @@db_spec_cache
|
||||
# just fake it for non multisite
|
||||
yield hostname
|
||||
return
|
||||
end
|
||||
|
||||
old = current_hostname
|
||||
connected = ActiveRecord::Base.connection_pool.connected?
|
||||
|
||||
establish_connection(:host => hostname) unless connected && hostname == old
|
||||
rval = yield hostname
|
||||
|
||||
unless connected && hostname == old
|
||||
ActiveRecord::Base.connection_handler.clear_active_connections!
|
||||
|
||||
establish_connection(:host => old)
|
||||
ActiveRecord::Base.connection_handler.clear_active_connections! unless connected
|
||||
end
|
||||
|
||||
rval
|
||||
end
|
||||
|
||||
def self.with_connection(db = "default")
|
||||
old = current_db
|
||||
connected = ActiveRecord::Base.connection_pool.connected?
|
||||
|
||||
establish_connection(:db => db) unless connected && db == old
|
||||
rval = yield db
|
||||
|
||||
unless connected && db == old
|
||||
ActiveRecord::Base.connection_handler.clear_active_connections!
|
||||
|
||||
establish_connection(:db => old)
|
||||
ActiveRecord::Base.connection_handler.clear_active_connections! unless connected
|
||||
end
|
||||
|
||||
rval
|
||||
end
|
||||
|
||||
def self.each_connection
|
||||
old = current_db
|
||||
connected = ActiveRecord::Base.connection_pool.connected?
|
||||
all_dbs.each do |db|
|
||||
establish_connection(:db => db)
|
||||
yield db
|
||||
ActiveRecord::Base.connection_handler.clear_active_connections!
|
||||
end
|
||||
establish_connection(:db => old)
|
||||
ActiveRecord::Base.connection_handler.clear_active_connections! unless connected
|
||||
end
|
||||
|
||||
def self.all_dbs
|
||||
["default"] +
|
||||
if defined?(@@db_spec_cache) && @@db_spec_cache
|
||||
@@db_spec_cache.keys.to_a
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def self.current_db
|
||||
ActiveRecord::Base.connection_pool.spec.config[:db_key] || "default"
|
||||
end
|
||||
|
||||
def self.config_filename=(config_filename)
|
||||
@@config_filename = config_filename
|
||||
end
|
||||
|
||||
def self.config_filename
|
||||
@@config_filename ||= File.absolute_path(Rails.root.to_s + "/" + RailsMultisite::ConnectionManagement::CONFIG_FILE)
|
||||
end
|
||||
|
||||
def self.current_hostname
|
||||
config = ActiveRecord::Base.connection_pool.spec.config
|
||||
config[:host_names].nil? ? config[:host] : config[:host_names].first
|
||||
end
|
||||
|
||||
def self.clear_settings!
|
||||
@@db_spec_cache = nil
|
||||
@@host_spec_cache = nil
|
||||
@@default_spec = nil
|
||||
end
|
||||
|
||||
def self.load_settings!
|
||||
spec_klass = ActiveRecord::ConnectionAdapters::ConnectionSpecification
|
||||
configs = YAML::load(File.open(self.config_filename))
|
||||
configs.each do |k,v|
|
||||
raise ArgumentError.new("Please do not name any db default!") if k == "default"
|
||||
v[:db_key] = k
|
||||
end
|
||||
|
||||
@@db_spec_cache = Hash[*configs.map do |k, data|
|
||||
[k, spec_klass::Resolver.new(configs).spec(k)]
|
||||
end.flatten]
|
||||
|
||||
@@host_spec_cache = {}
|
||||
configs.each do |k,v|
|
||||
next unless v["host_names"]
|
||||
v["host_names"].each do |host|
|
||||
@@host_spec_cache[host] = @@db_spec_cache[k]
|
||||
end
|
||||
end
|
||||
|
||||
@@default_spec = spec_klass::Resolver.new(ActiveRecord::Base.configurations).spec(Rails.env)
|
||||
ActiveRecord::Base.configurations[Rails.env]["host_names"].each do |host|
|
||||
@@host_spec_cache[host] = @@default_spec
|
||||
end
|
||||
|
||||
@@default_connection_handler = ActiveRecord::Base.connection_handler
|
||||
|
||||
@@connection_handlers = {}
|
||||
@@established_default = false
|
||||
end
|
||||
|
||||
|
||||
def initialize(app, config = nil)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def self.host(env)
|
||||
request = Rack::Request.new(env)
|
||||
request['__ws'] || request.host
|
||||
end
|
||||
|
||||
def call(env)
|
||||
host = self.class.host(env)
|
||||
begin
|
||||
|
||||
#TODO: add a callback so users can simply go to a domain to register it, or something
|
||||
return [404, {}, ["not found"]] unless @@host_spec_cache[host]
|
||||
|
||||
ActiveRecord::Base.connection_handler.clear_active_connections!
|
||||
self.class.establish_connection(:host => host)
|
||||
@app.call(env)
|
||||
ensure
|
||||
ActiveRecord::Base.connection_handler.clear_active_connections!
|
||||
end
|
||||
end
|
||||
|
||||
def self.connection_spec(opts)
|
||||
if opts[:host]
|
||||
@@host_spec_cache[opts[:host]]
|
||||
else
|
||||
@@db_spec_cache[opts[:db]]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
module RailsMultisite
|
||||
class Railtie < Rails::Railtie
|
||||
rake_tasks do
|
||||
Dir[File.join(File.dirname(__FILE__),'../tasks/*.rake')].each { |f| load f }
|
||||
end
|
||||
|
||||
initializer "RailsMultisite.init" do |app|
|
||||
Rails.configuration.multisite = false
|
||||
if File.exists?(ConnectionManagement.config_filename)
|
||||
Rails.configuration.multisite = true
|
||||
ConnectionManagement.load_settings!
|
||||
app.middleware.insert_after(ActiveRecord::ConnectionAdapters::ConnectionManagement, RailsMultisite::ConnectionManagement)
|
||||
app.middleware.delete(ActiveRecord::ConnectionAdapters::ConnectionManagement)
|
||||
if ENV['RAILS_DB']
|
||||
ConnectionManagement.establish_connection(:db => ENV['RAILS_DB'])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
module RailsMultisite
|
||||
VERSION = "0.0.1"
|
||||
end
|
|
@ -1,31 +0,0 @@
|
|||
desc "migrate all sites in tier"
|
||||
task "multisite:migrate" => :environment do
|
||||
RailsMultisite::ConnectionManagement.each_connection do |db|
|
||||
puts "Migrating #{db}"
|
||||
puts "---------------------------------\n"
|
||||
t = Rake::Task["db:migrate"]
|
||||
t.reenable
|
||||
t.invoke
|
||||
end
|
||||
end
|
||||
|
||||
task "multisite:seed_fu" => :environment do
|
||||
RailsMultisite::ConnectionManagement.each_connection do |db|
|
||||
puts "Seeding #{db}"
|
||||
puts "---------------------------------\n"
|
||||
t = Rake::Task["db:seed_fu"]
|
||||
t.reenable
|
||||
t.invoke
|
||||
end
|
||||
end
|
||||
|
||||
desc "rollback migrations for all sites in tier"
|
||||
task "multisite:rollback" => :environment do
|
||||
RailsMultisite::ConnectionManagement.each_connection do |db|
|
||||
puts "Rollback #{db}"
|
||||
puts "---------------------------------\n"
|
||||
t = Rake::Task["db:rollback"]
|
||||
t.reenable
|
||||
t.invoke
|
||||
end
|
||||
end
|
|
@ -1,26 +0,0 @@
|
|||
desc "generate multisite config file (if missing)"
|
||||
task "multisite:generate:config" => :environment do
|
||||
filename = RailsMultisite::ConnectionManagement.config_filename
|
||||
|
||||
if File.exists?(filename)
|
||||
puts "Config is already generated at #{RailsMultisite::ConnectionManagement::CONFIG_FILE}"
|
||||
else
|
||||
puts "Generated config file at #{RailsMultisite::ConnectionManagement::CONFIG_FILE}"
|
||||
File.open(filename, 'w') do |f|
|
||||
f.write <<-CONFIG
|
||||
# site_name:
|
||||
# adapter: postgresql
|
||||
# database: db_name
|
||||
# host: localhost
|
||||
# pool: 5
|
||||
# timeout: 5000
|
||||
# db_id: 1 # optionally include other settings you need
|
||||
# host_names:
|
||||
# - www.mysite.com
|
||||
# - www.anothersite.com
|
||||
CONFIG
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -1,20 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
require File.expand_path('../lib/rails_multisite/version', __FILE__)
|
||||
|
||||
Gem::Specification.new do |gem|
|
||||
gem.authors = ["Sam Saffron"]
|
||||
gem.email = ["sam.saffron@gmail.com"]
|
||||
gem.description = %q{Multi tenancy support for Rails}
|
||||
gem.summary = %q{Multi tenancy support for Rails}
|
||||
gem.homepage = ""
|
||||
|
||||
# when this is extracted comment it back in, prd has no .git
|
||||
# gem.files = `git ls-files`.split($\)
|
||||
gem.files = Dir['README*','LICENSE','lib/**/*.rb']
|
||||
|
||||
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
||||
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
||||
gem.name = "rails_multisite"
|
||||
gem.require_paths = ["lib"]
|
||||
gem.version = RailsMultisite::VERSION
|
||||
end
|
|
@ -1,47 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require 'rails_multisite'
|
||||
require 'rack/test'
|
||||
|
||||
describe RailsMultisite::ConnectionManagement do
|
||||
include Rack::Test::Methods
|
||||
|
||||
def app
|
||||
|
||||
RailsMultisite::ConnectionManagement.config_filename = 'spec/fixtures/two_dbs.yml'
|
||||
RailsMultisite::ConnectionManagement.load_settings!
|
||||
|
||||
@app ||= Rack::Builder.new {
|
||||
use RailsMultisite::ConnectionManagement
|
||||
map '/html' do
|
||||
run lambda { |env| [200, {'Content-Type' => 'text/html'}, "<html><BODY><h1>Hi</h1></BODY>\n \t</html>"] }
|
||||
end
|
||||
}.to_app
|
||||
end
|
||||
|
||||
after do
|
||||
RailsMultisite::ConnectionManagement.clear_settings!
|
||||
end
|
||||
|
||||
describe 'with a valid request' do
|
||||
|
||||
before do
|
||||
end
|
||||
|
||||
it 'returns 200 for valid site' do
|
||||
get 'http://second.localhost/html'
|
||||
last_response.should be_ok
|
||||
end
|
||||
|
||||
it 'returns 200 for valid main site' do
|
||||
get 'http://default.localhost/html'
|
||||
last_response.should be_ok
|
||||
end
|
||||
|
||||
it 'returns 404 for invalid site' do
|
||||
get '/html'
|
||||
last_response.should be_not_found
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require 'rails_multisite'
|
||||
|
||||
class Person < ActiveRecord::Base; end
|
||||
|
||||
describe RailsMultisite::ConnectionManagement do
|
||||
|
||||
subject { RailsMultisite::ConnectionManagement }
|
||||
|
||||
def with_connection(db)
|
||||
subject.establish_connection(db: db)
|
||||
yield ActiveRecord::Base.connection.raw_connection
|
||||
ensure
|
||||
ActiveRecord::Base.connection_handler.clear_active_connections!
|
||||
end
|
||||
|
||||
context 'default' do
|
||||
its(:all_dbs) { should == ['default']}
|
||||
|
||||
context 'current' do
|
||||
before do
|
||||
subject.establish_connection(db: 'default')
|
||||
ActiveRecord::Base.establish_connection
|
||||
end
|
||||
|
||||
its(:current_db) { should == 'default' }
|
||||
its(:current_hostname) { should == 'default.localhost' }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'two dbs' do
|
||||
|
||||
before do
|
||||
subject.config_filename = "spec/fixtures/two_dbs.yml"
|
||||
subject.load_settings!
|
||||
end
|
||||
|
||||
its(:all_dbs) { should == ['default', 'second']}
|
||||
|
||||
context 'second db' do
|
||||
before do
|
||||
subject.establish_connection(db: 'second')
|
||||
end
|
||||
|
||||
its(:current_db) { should == 'second' }
|
||||
its(:current_hostname) { should == "second.localhost" }
|
||||
end
|
||||
|
||||
context 'data partitioning' do
|
||||
after do
|
||||
['default','second'].each do |db|
|
||||
with_connection(db) do |cnn|
|
||||
cnn.execute("drop table people") rescue nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'partitions data correctly' do
|
||||
col1 = []
|
||||
col2 = []
|
||||
|
||||
['default','second'].map do |db|
|
||||
|
||||
with_connection(db) do |cnn|
|
||||
cnn.execute("create table if not exists people(id INTEGER PRIMARY KEY AUTOINCREMENT, db)")
|
||||
end
|
||||
end
|
||||
|
||||
SQLite3::Database.query_log.clear
|
||||
|
||||
5.times do
|
||||
['default','second'].map do |db|
|
||||
Thread.new do
|
||||
with_connection(db) do |cnn|
|
||||
Person.create!(db: db)
|
||||
end
|
||||
end
|
||||
end.map(&:join)
|
||||
end
|
||||
|
||||
lists = []
|
||||
['default', 'second'].each do |db|
|
||||
with_connection(db) do |cnn|
|
||||
lists << Person.order(:id).to_a.map{|p| [p.id, p.db]}
|
||||
end
|
||||
end
|
||||
|
||||
lists[1].should == (1..5).map{|id| [id, "second"]}
|
||||
lists[0].should == (1..5).map{|id| [id, "default"]}
|
||||
|
||||
# puts SQLite3::Database.query_log.map{|args, caller, oid| "#{oid} #{args.join.inspect}"}.join("\n")
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -1,6 +0,0 @@
|
|||
test:
|
||||
adapter: sqlite3
|
||||
database: "tmp/db.test"
|
||||
timeout: 5000
|
||||
host_names:
|
||||
- default.localhost
|
|
@ -1,6 +0,0 @@
|
|||
second:
|
||||
adapter: sqlite3
|
||||
database: "tmp/db1.test"
|
||||
host_names:
|
||||
- second.localhost
|
||||
- 2nd.localhost
|
|
@ -1,38 +0,0 @@
|
|||
require 'rubygems'
|
||||
require 'rails'
|
||||
require 'active_record'
|
||||
|
||||
|
||||
ENV["RAILS_ENV"] ||= 'test'
|
||||
RSpec.configure do |config|
|
||||
|
||||
require 'sqlite3'
|
||||
class SQLite3::Database
|
||||
def self.query_log
|
||||
@@query_log ||= []
|
||||
end
|
||||
|
||||
alias_method :old_execute, :execute
|
||||
alias_method :old_prepare, :prepare
|
||||
|
||||
def execute(*args,&blk)
|
||||
self.class.query_log << [args, caller, Thread.current.object_id]
|
||||
old_execute(*args,&blk)
|
||||
end
|
||||
|
||||
def prepare(*args,&blk)
|
||||
self.class.query_log << [args, caller, Thread.current.object_id]
|
||||
old_prepare(*args,&blk)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
config.color_enabled = true
|
||||
|
||||
config.before(:suite) do
|
||||
ActiveRecord::Base.configurations['test'] = (YAML::load(File.open("spec/fixtures/database.yml"))['test'])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue