Permalink
Browse files

elevators are now sharing code

  • Loading branch information...
1 parent 1e09ea2 commit e3b65b6b12e1a416a8d16dbcc8a8210edccecbfd @bradrobertson bradrobertson committed Jun 1, 2012
View
@@ -45,8 +45,9 @@ module Adapters
end
module Elevators
- autoload :Subdomain, 'apartment/elevators/subdomain'
- autoload :Domain, 'apartment/elevators/domain'
+ autoload :Generic, 'apartment/elevators/generic'
+ autoload :Subdomain, 'apartment/elevators/subdomain'
+ autoload :Domain, 'apartment/elevators/domain'
end
module Delayed
@@ -1,32 +1,18 @@
module Apartment
module Elevators
- # Provides a rack based db switching solution based on domain
- # Assumes that database name should match domain
- # Parses request host for second level domain
- # eg. example.com => example
- # www.example.bc.ca => example
- class Domain
-
- def initialize(app)
- @app = app
- end
-
- def call(env)
- request = ActionDispatch::Request.new(env)
-
- database = domain(request)
-
- Apartment::Database.switch database if database
-
- @app.call(env)
- end
-
- def domain(request)
+ # Provides a rack based db switching solution based on domain
+ # Assumes that database name should match domain
+ # Parses request host for second level domain
+ # eg. example.com => example
+ # www.example.bc.ca => example
+ #
+ class Domain < Generic
+
+ def process(request)
return nil if request.host.blank?
request.host.match(/(www.)?(?<sld>[^.]*)/)["sld"]
end
-
end
end
end
@@ -0,0 +1,27 @@
+module Apartment
+ module Elevators
+ # Provides a rack based db switching solution based on request
+ #
+ class Generic
+
+ def initialize(app, processor = nil)
+ @app = app
+ @processor = processor || method(:process)
+ end
+
+ def call(env)
+ request = ActionDispatch::Request.new(env)
+
+ database = @processor.call(request)
+
+ Apartment::Database.switch database if database
+
+ @app.call(env)
+ end
+
+ def process(request)
+ raise "Override"
+ end
+ end
+ end
+end
@@ -1,27 +1,13 @@
module Apartment
module Elevators
- # Provides a rack based db switching solution based on subdomains
- # Assumes that database name should match subdomain
- class Subdomain
+ # Provides a rack based db switching solution based on subdomains
+ # Assumes that database name should match subdomain
+ #
+ class Subdomain < Generic
- def initialize(app)
- @app = app
- end
-
- def call(env)
- request = ActionDispatch::Request.new(env)
-
- database = subdomain(request)
-
- Apartment::Database.switch database if database
-
- @app.call(env)
- end
-
- def subdomain(request)
+ def process(request)
request.subdomain.present? && request.subdomain || nil
end
-
end
end
end
View
@@ -11,13 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20111202022214) do
-
- create_table "books", :force => true do |t|
- t.string "name"
- t.integer "pages"
- t.datetime "published"
- end
+ActiveRecord::Schema.define(:version => 20110613152810) do
create_table "companies", :force => true do |t|
t.boolean "dummy"
@@ -2,30 +2,30 @@
shared_examples_for "a db based apartment adapter" do
include Apartment::Spec::AdapterRequirements
-
+
let(:default_database){ subject.process{ ActiveRecord::Base.connection.current_database } }
-
+
describe "#init" do
-
+
it "should process model exclusions" do
Apartment.configure do |config|
config.excluded_models = ["Company"]
end
-
+
Apartment::Database.init
-
+
Company.connection.object_id.should_not == ActiveRecord::Base.connection.object_id
end
end
-
+
describe "#drop" do
it "should raise an error for unknown database" do
expect {
subject.drop 'unknown_database'
}.to raise_error(Apartment::DatabaseNotFound)
end
- end
-
+ end
+
describe "#switch" do
it "should raise an error if database is invalid" do
expect {
@@ -0,0 +1,31 @@
+require 'spec_helper'
+
+shared_examples_for "an apartment elevator" do
+
+ context "single request" do
+ it "should switch the db" do
+ ActiveRecord::Base.connection.schema_search_path.should_not == database1
+
+ visit(domain1)
+ ActiveRecord::Base.connection.schema_search_path.should == database1
+ end
+ end
+
+ context "simultaneous requests" do
+
+ let!(:c1_user_count) { api.process(database1){ (2 + rand(2)).times{ User.create } } }
+ let!(:c2_user_count) { api.process(database2){ (c1_user_count + 2).times{ User.create } } }
+
+ it "should fetch the correct user count for each session based on the elevator processor" do
+ visit(domain1)
+
+ in_new_session do |session|
+ session.visit(domain2)
+ User.count.should == c2_user_count
+ end
+
+ visit(domain1)
+ User.count.should == c1_user_count
+ end
+ end
+end
@@ -1,52 +1,9 @@
require 'spec_helper'
-describe Apartment::Elevators::Domain do
+describe Apartment::Elevators::Domain, :elevator => true do
- let(:company){ mock_model(Company, :domain => 'foo').as_null_object }
- let(:domain){ "http://#{company.domain}.com" }
- let(:api){ Apartment::Database }
-
- before do
- Apartment.seed_after_create = false
- Apartment.use_postgres_schemas = true
-
- api.create(company.domain)
- end
-
- after{ api.drop(company.domain) }
-
- context "single request" do
- it "should switch the db" do
- ActiveRecord::Base.connection.schema_search_path.should_not == company.domain
-
- visit(domain)
- ActiveRecord::Base.connection.schema_search_path.should == company.domain
- end
- end
-
- context "simultaneous requests" do
- let(:company2){ mock_model(Company, :domain => 'bar').as_null_object }
- let(:domain2){ "http://#{company2.domain}.com" }
-
- before{ api.create(company2.domain) }
- after{ api.drop(company2.domain) }
-
- let!(:c1_user_count){ api.process(company.domain){ (2 + rand(2)).times{ User.create } } }
- let!(:c2_user_count){ api.process(company2.domain){ (c1_user_count + 2).times{ User.create } } }
-
- it "should fetch the correct user count for each session based on domain" do
- visit(domain)
-
- in_new_session do |session|
- session.visit(domain2)
- User.count.should == c2_user_count
- end
-
- visit(domain)
- User.count.should == c1_user_count
- end
-
-
- end
+ let(:domain1) { "http://#{database1}.com" }
+ let(:domain2) { "http://#{database2}.com" }
+ it_should_behave_like "an apartment elevator"
end
@@ -1,52 +1,9 @@
require 'spec_helper'
-describe Apartment::Elevators::Subdomain do
-
- let(:company){ mock_model(Company, :subdomain => 'foo').as_null_object }
- let(:domain){ "http://#{company.subdomain}.domain.com" }
- let(:api){ Apartment::Database }
-
- before do
- Apartment.seed_after_create = false
- Apartment.use_postgres_schemas = true
-
- api.create(company.subdomain)
- end
-
- after{ api.drop(company.subdomain) }
-
- context "single request" do
- it "should switch the db" do
- ActiveRecord::Base.connection.schema_search_path.should_not == company.subdomain
-
- visit(domain)
- ActiveRecord::Base.connection.schema_search_path.should == company.subdomain
- end
- end
-
- context "simultaneous requests" do
- let(:company2){ mock_model(Company, :subdomain => 'bar').as_null_object }
- let(:domain2){ "http://#{company2.subdomain}.domain.com" }
-
- before{ api.create(company2.subdomain) }
- after{ api.drop(company2.subdomain) }
-
- let!(:c1_user_count){ api.process(company.subdomain){ (2 + rand(2)).times{ User.create } } }
- let!(:c2_user_count){ api.process(company2.subdomain){ (c1_user_count + 2).times{ User.create } } }
-
- it "should fetch the correct user count for each session based on subdomain" do
- visit(domain)
-
- in_new_session do |session|
- session.visit(domain2)
- User.count.should == c2_user_count
- end
-
- visit(domain)
- User.count.should == c1_user_count
- end
-
-
- end
-
+describe Apartment::Elevators::Subdomain, :elevator => true do
+
+ let(:domain1) { "http://#{database1}.example.com" }
+ let(:domain2) { "http://#{database2}.example.com" }
+
+ it_should_behave_like "an apartment elevator"
end
@@ -12,7 +12,7 @@ def reset
def next_db
@x ||= 0
- "db_#{@x += 1}"
+ "db%d" % @x += 1
end
def drop_schema(schema)
View
@@ -13,4 +13,28 @@
Apartment.default_schema = nil
Apartment::Test.drop_schema(default_schema)
end
+end
+
+# Some default setup for elevator specs
+shared_context "elevators", :elevator => true do
+ let(:company1) { mock_model(Company, :database => Apartment::Test.next_db).as_null_object }
+ let(:company2) { mock_model(Company, :database => Apartment::Test.next_db).as_null_object }
+
+ let(:database1) { company1.database }
+ let(:database2) { company2.database }
+
+ let(:api) { Apartment::Database }
+
+ before do
+ Apartment.seed_after_create = false
+ Apartment.use_postgres_schemas = true
+
+ api.create(database1)
+ api.create(database2)
+ end
+
+ after do
+ api.drop(database1)
+ api.drop(database2)
+ end
end
@@ -2,23 +2,23 @@
describe Apartment::Elevators::Domain do
- describe "#domain" do
+ describe "#process" do
it "parses the host for a domain name" do
request = ActionDispatch::Request.new('HTTP_HOST' => 'example.com')
elevator = Apartment::Elevators::Domain.new(nil)
- elevator.domain(request).should == 'example'
+ elevator.process(request).should == 'example'
end
it "ignores a www prefix and domain suffix" do
request = ActionDispatch::Request.new('HTTP_HOST' => 'www.example.bc.ca')
elevator = Apartment::Elevators::Domain.new(nil)
- elevator.domain(request).should == 'example'
+ elevator.process(request).should == 'example'
end
it "returns nil if there is no host" do
request = ActionDispatch::Request.new('HTTP_HOST' => '')
elevator = Apartment::Elevators::Domain.new(nil)
- elevator.domain(request).should be_nil
+ elevator.process(request).should be_nil
end
end
Oops, something went wrong.

0 comments on commit e3b65b6

Please sign in to comment.