stop vendoring rails multisite

This commit is contained in:
Sam 2015-10-12 17:26:20 +11:00
parent e17978a203
commit cf52671feb
20 changed files with 5 additions and 597 deletions

View file

@ -35,7 +35,9 @@ gem 'barber'
gem 'babel-transpiler' gem 'babel-transpiler'
gem 'message_bus' 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' gem 'fast_xs'

View file

@ -1,8 +1,3 @@
PATH
remote: vendor/gems/rails_multisite
specs:
rails_multisite (0.0.1)
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
@ -304,6 +299,7 @@ GEM
loofah (~> 2.0) loofah (~> 2.0)
rails-observers (0.1.2) rails-observers (0.1.2)
activemodel (~> 4.0) activemodel (~> 4.0)
rails_multisite_discourse (1.0.0)
railties (4.2.4) railties (4.2.4)
actionpack (= 4.2.4) actionpack (= 4.2.4)
activesupport (= 4.2.4) activesupport (= 4.2.4)
@ -504,7 +500,7 @@ DEPENDENCIES
rack-protection rack-protection
rails (~> 4.2) rails (~> 4.2)
rails-observers rails-observers
rails_multisite! rails_multisite_discourse
rake rake
rb-fsevent rb-fsevent
rb-inotify (~> 0.9) rb-inotify (~> 0.9)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -1,3 +0,0 @@
require "rails_multisite/version"
require "rails_multisite/railtie"
require "rails_multisite/connection_management"

View file

@ -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

View file

@ -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

View file

@ -1,3 +0,0 @@
module RailsMultisite
VERSION = "0.0.1"
end

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -1,6 +0,0 @@
test:
adapter: sqlite3
database: "tmp/db.test"
timeout: 5000
host_names:
- default.localhost

View file

@ -1,6 +0,0 @@
second:
adapter: sqlite3
database: "tmp/db1.test"
host_names:
- second.localhost
- 2nd.localhost

View file

@ -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