dbhijacker 0.9.2 → 0.10.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c90889f2261a0bc334b4f397386a14f0830f8072
4
- data.tar.gz: c568919019f38132fe1e1bff68c3f48d1aecd8d9
3
+ metadata.gz: 534c79458c53e9f6cd0a858a830ca956aa4589de
4
+ data.tar.gz: 1a99b7b0f639f24b99a834b390031ee15c3d2508
5
5
  SHA512:
6
- metadata.gz: 3f6808340f674aaa39808b9daa78709a0f9e818dfde021013d94809a6c5a192fb1680ecb46016896cae8c5e2d36b9a150f69f7d8ef6fa36a9f28d4d81b37ae69
7
- data.tar.gz: e880f040e50e4c0791055df860034070a0920dc65724f7eb904db4a877bcb8934eb7e5a7bda03594847bcd7e0203bda8747ee6b74324b529b449de2e77b7fdce
6
+ metadata.gz: 9185d392c8d2d3451fa3a693cac9e44a53dbffbecf67b2b57cba763f5894c6ab68463cc87a04a15120f339dc4d41b04610d95dd4c0725d8c0dff70876b592ce5
7
+ data.tar.gz: 2e4e921fdcd69cf7d058664b0cf553138e6557a409c3619e234c0c58045d1278b111f5f94827383368ec6638332ea5eb5e99ce21520869a5e226b209d02aca72
data/Gemfile.lock CHANGED
@@ -1,52 +1,181 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dbhijacker (0.9.2)
5
- rails (>= 2.3.14)
4
+ dbhijacker (0.10.0)
5
+ rails (>= 2.3.14, < 4.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- actionmailer (2.3.18)
11
- actionpack (= 2.3.18)
12
- actionpack (2.3.18)
13
- activesupport (= 2.3.18)
14
- rack (~> 1.1.0)
15
- activerecord (2.3.18)
16
- activesupport (= 2.3.18)
17
- activeresource (2.3.18)
18
- activesupport (= 2.3.18)
19
- activesupport (2.3.18)
20
- diff-lcs (1.2.3)
21
- rack (1.1.6)
10
+ actionmailer (3.2.18)
11
+ actionpack (= 3.2.18)
12
+ mail (~> 2.5.4)
13
+ actionpack (3.2.18)
14
+ activemodel (= 3.2.18)
15
+ activesupport (= 3.2.18)
16
+ builder (~> 3.0.0)
17
+ erubis (~> 2.7.0)
18
+ journey (~> 1.0.4)
19
+ rack (~> 1.4.5)
20
+ rack-cache (~> 1.2)
21
+ rack-test (~> 0.6.1)
22
+ sprockets (~> 2.2.1)
23
+ activemodel (3.2.18)
24
+ activesupport (= 3.2.18)
25
+ builder (~> 3.0.0)
26
+ activerecord (3.2.18)
27
+ activemodel (= 3.2.18)
28
+ activesupport (= 3.2.18)
29
+ arel (~> 3.0.2)
30
+ tzinfo (~> 0.3.29)
31
+ activeresource (3.2.18)
32
+ activemodel (= 3.2.18)
33
+ activesupport (= 3.2.18)
34
+ activesupport (3.2.18)
35
+ i18n (~> 0.6, >= 0.6.4)
36
+ multi_json (~> 1.0)
37
+ addressable (2.3.6)
38
+ arel (3.0.3)
39
+ builder (3.0.4)
40
+ celluloid (0.15.2)
41
+ timers (~> 1.1.0)
42
+ coderay (1.1.0)
43
+ descendants_tracker (0.0.4)
44
+ thread_safe (~> 0.3, >= 0.3.1)
45
+ diff-lcs (1.2.5)
46
+ erubis (2.7.0)
47
+ faraday (0.9.0)
48
+ multipart-post (>= 1.2, < 3)
49
+ ffi (1.9.3)
50
+ formatador (0.2.5)
51
+ git (1.2.7)
52
+ github_api (0.11.3)
53
+ addressable (~> 2.3)
54
+ descendants_tracker (~> 0.0.1)
55
+ faraday (~> 0.8, < 0.10)
56
+ hashie (>= 1.2)
57
+ multi_json (>= 1.7.5, < 2.0)
58
+ nokogiri (~> 1.6.0)
59
+ oauth2
60
+ guard (2.6.1)
61
+ formatador (>= 0.2.4)
62
+ listen (~> 2.7)
63
+ lumberjack (~> 1.0)
64
+ pry (>= 0.9.12)
65
+ thor (>= 0.18.1)
66
+ guard-bundler (2.0.0)
67
+ bundler (~> 1.0)
68
+ guard (~> 2.2)
69
+ guard-rspec (4.2.10)
70
+ guard (~> 2.1)
71
+ rspec (>= 2.14, < 4.0)
72
+ hashie (3.0.0)
73
+ highline (1.6.21)
74
+ hike (1.2.3)
75
+ i18n (0.6.9)
76
+ jeweler (2.0.1)
77
+ builder
78
+ bundler (>= 1.0)
79
+ git (>= 1.2.5)
80
+ github_api
81
+ highline (>= 1.6.15)
82
+ nokogiri (>= 1.5.10)
83
+ rake
84
+ rdoc
85
+ journey (1.0.4)
86
+ json (1.8.1)
87
+ jwt (1.0.0)
88
+ listen (2.7.8)
89
+ celluloid (>= 0.15.2)
90
+ rb-fsevent (>= 0.9.3)
91
+ rb-inotify (>= 0.9)
92
+ lumberjack (1.0.6)
93
+ mail (2.5.4)
94
+ mime-types (~> 1.16)
95
+ treetop (~> 1.4.8)
96
+ method_source (0.8.2)
97
+ mime-types (1.25.1)
98
+ mini_portile (0.6.0)
99
+ multi_json (1.10.1)
100
+ multi_xml (0.5.5)
101
+ multipart-post (2.0.0)
102
+ nokogiri (1.6.2.1)
103
+ mini_portile (= 0.6.0)
104
+ oauth2 (0.9.4)
105
+ faraday (>= 0.8, < 0.10)
106
+ jwt (~> 1.0)
107
+ multi_json (~> 1.3)
108
+ multi_xml (~> 0.5)
109
+ rack (~> 1.2)
110
+ polyglot (0.3.5)
111
+ pry (0.10.0)
112
+ coderay (~> 1.1.0)
113
+ method_source (~> 0.8.1)
114
+ slop (~> 3.4)
115
+ rack (1.4.5)
116
+ rack-cache (1.2)
117
+ rack (>= 0.4)
118
+ rack-ssl (1.3.4)
119
+ rack
22
120
  rack-test (0.6.2)
23
121
  rack (>= 1.0)
24
- rails (2.3.18)
25
- actionmailer (= 2.3.18)
26
- actionpack (= 2.3.18)
27
- activerecord (= 2.3.18)
28
- activeresource (= 2.3.18)
29
- activesupport (= 2.3.18)
30
- rake (>= 0.8.3)
31
- rake (0.9.6)
32
- rspec (2.13.0)
33
- rspec-core (~> 2.13.0)
34
- rspec-expectations (~> 2.13.0)
35
- rspec-mocks (~> 2.13.0)
36
- rspec-core (2.13.1)
37
- rspec-expectations (2.13.0)
122
+ rails (3.2.18)
123
+ actionmailer (= 3.2.18)
124
+ actionpack (= 3.2.18)
125
+ activerecord (= 3.2.18)
126
+ activeresource (= 3.2.18)
127
+ activesupport (= 3.2.18)
128
+ bundler (~> 1.0)
129
+ railties (= 3.2.18)
130
+ railties (3.2.18)
131
+ actionpack (= 3.2.18)
132
+ activesupport (= 3.2.18)
133
+ rack-ssl (~> 1.3.2)
134
+ rake (>= 0.8.7)
135
+ rdoc (~> 3.4)
136
+ thor (>= 0.14.6, < 2.0)
137
+ rake (10.3.2)
138
+ rb-fsevent (0.9.4)
139
+ rb-inotify (0.9.5)
140
+ ffi (>= 0.5.0)
141
+ rdoc (3.12.2)
142
+ json (~> 1.4)
143
+ rspec (2.99.0)
144
+ rspec-core (~> 2.99.0)
145
+ rspec-expectations (~> 2.99.0)
146
+ rspec-mocks (~> 2.99.0)
147
+ rspec-core (2.99.0)
148
+ rspec-expectations (2.99.0)
38
149
  diff-lcs (>= 1.1.3, < 2.0)
39
- rspec-mocks (2.13.1)
40
- sqlite3 (1.3.7)
150
+ rspec-mocks (2.99.1)
151
+ slop (3.5.0)
152
+ sprockets (2.2.2)
153
+ hike (~> 1.2)
154
+ multi_json (~> 1.0)
155
+ rack (~> 1.0)
156
+ tilt (~> 1.1, != 1.3.0)
157
+ sqlite3 (1.3.9)
158
+ thor (0.19.1)
159
+ thread_safe (0.3.4)
160
+ tilt (1.4.1)
161
+ timers (1.1.0)
162
+ treetop (1.4.15)
163
+ polyglot
164
+ polyglot (>= 0.3.1)
165
+ tzinfo (0.3.39)
41
166
 
42
167
  PLATFORMS
43
168
  ruby
44
169
 
45
170
  DEPENDENCIES
46
- bundler (>= 1.3)
171
+ bundler
47
172
  dbhijacker!
173
+ guard
174
+ guard-bundler
175
+ guard-rspec
176
+ jeweler
48
177
  rack (>= 1.1.0)
49
178
  rack-test (>= 0.6.1)
50
179
  rake (>= 0.9.2)
51
- rspec (>= 2.8)
52
- sqlite3 (>= 1.3.5)
180
+ rspec (~> 2.8)
181
+ sqlite3 (~> 1.3.5)
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'rake'
2
- require 'rake/rdoctask'
2
+ require 'rdoc/task'
3
3
 
4
4
 
5
5
  desc 'Generate documentation for the hijacker plugin.'
data/dbhijacker.gemspec CHANGED
@@ -3,23 +3,27 @@
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{dbhijacker}
5
5
  s.homepage = "https://github.com/crystalcommerce/hijacker"
6
- s.version = "0.9.2"
6
+ s.version = "0.10.0"
7
7
 
8
8
  s.license = "MIT"
9
9
 
10
10
  s.authors = ["Michael Xavier", "Donald Plummer", "Woody Peterson"]
11
- s.date = %q{2012-03-21}
11
+ s.date = %q{2014-06-18}
12
12
  s.description = %q{Allows a single Rails appliation to access many different databases}
13
13
  s.email = %q{developers@crystalcommerce.com}
14
14
 
15
- s.add_dependency("rails", ">= 2.3.14")
15
+ s.add_dependency("rails", ">= 2.3.14", "< 4.0")
16
16
 
17
- s.add_development_dependency "bundler", ">= 1.3"
17
+ s.add_development_dependency "jeweler"
18
+ s.add_development_dependency "bundler"
19
+ s.add_development_dependency "guard"
20
+ s.add_development_dependency "guard-rspec"
21
+ s.add_development_dependency "guard-bundler"
18
22
  s.add_development_dependency "rake", ">= 0.9.2"
19
23
  s.add_development_dependency "rack-test", ">= 0.6.1"
20
24
  s.add_development_dependency "rack", ">= 1.1.0"
21
- s.add_development_dependency "rspec", ">= 2.8"
22
- s.add_development_dependency "sqlite3", ">= 1.3.5"
25
+ s.add_development_dependency "rspec", "~> 2.8"
26
+ s.add_development_dependency "sqlite3", "~> 1.3.5"
23
27
 
24
28
  s.extra_rdoc_files = [
25
29
  "README.rdoc"
@@ -5,7 +5,7 @@ ActiveRecord::Schema.define(:version => 2) do
5
5
  t.integer "host_id"
6
6
  end
7
7
 
8
- add_index "databases", "database"
8
+ add_index "databases", "database", :unique => true
9
9
  add_index "databases", "master_id"
10
10
 
11
11
  create_table "aliases", :force => true do |t|
@@ -13,7 +13,7 @@ ActiveRecord::Schema.define(:version => 2) do
13
13
  t.string "name"
14
14
  end
15
15
 
16
- add_index "aliases", "name"
16
+ add_index "aliases", "name", :unique => true
17
17
 
18
18
  create_table "hosts", :force => true do |t|
19
19
  t.string "hostname"
data/lib/hijacker.rb CHANGED
@@ -1,11 +1,18 @@
1
1
  require 'hijacker/active_record_ext'
2
+ require 'hijacker/request_parser'
2
3
  require 'active_record'
3
4
  require 'action_controller'
4
5
  require 'set'
5
6
 
6
7
  module Hijacker
7
8
  class UnparseableURL < StandardError;end
8
- class InvalidDatabase < StandardError;end
9
+ class InvalidDatabase < StandardError
10
+ attr_reader :database
11
+ def initialize(database, message = "Database #{database} not found")
12
+ @database = database
13
+ super(message)
14
+ end
15
+ end
9
16
 
10
17
  class << self
11
18
  attr_accessor :config, :master, :sister
@@ -21,21 +28,21 @@ module Hijacker
21
28
  end
22
29
 
23
30
  # Manually establishes a new connection to the database.
24
- #
31
+ #
25
32
  # Background: every time rails gets information
26
33
  # from the database, it uses the last established connection. So,
27
34
  # although we've already established a connection to a root db
28
35
  # ("crystal", in this case), if we establish a new connection, all
29
36
  # subsequent database calls will use these settings instead (well,
30
37
  # until it's called again when it gets another request).
31
- #
38
+ #
32
39
  # Note that you can manually call this from script/console (or wherever)
33
40
  # to connect to the database you want, ex Hijacker.connect("database")
34
41
  def self.connect(target_name, sister_name = nil, options = {})
35
42
  original_database = Hijacker::Database.current
36
43
 
37
44
  begin
38
- raise InvalidDatabase, 'master cannot be nil' if target_name.nil?
45
+ raise InvalidDatabase.new(nil, 'master cannot be nil') if target_name.nil?
39
46
 
40
47
  target_name = target_name.downcase
41
48
  sister_name = sister_name.downcase unless sister_name.nil?
@@ -102,7 +109,7 @@ module Hijacker
102
109
  klass.connection
103
110
  rescue
104
111
  klass.establish_connection(root_config)
105
- raise Hijacker::InvalidDatabase, database.name
112
+ raise Hijacker::InvalidDatabase.new(database.name)
106
113
  end
107
114
  master_db_connection_pool = klass.connection_pool
108
115
  else
@@ -123,9 +130,7 @@ module Hijacker
123
130
 
124
131
  result
125
132
  end
126
-
127
- # maintains and returns a connection to the root database.
128
- #
133
+
129
134
  # The advantage of using this over just calling
130
135
  # ActiveRecord::Base.establish_connection (without arguments) to reconnect
131
136
  # to the root database is that reusing the same connection greatly reduces
@@ -133,7 +138,7 @@ module Hijacker
133
138
  # the database. It may seem trivial, but it actually seems to speed things
134
139
  # up by ~ 1/3 for already fast requests (probably less noticeable on slower
135
140
  # pages).
136
- #
141
+ #
137
142
  # Note: does not hijack, just returns the root connection (i.e. AR::Base will
138
143
  # maintain its connection)
139
144
  def self.root_connection
@@ -180,7 +185,7 @@ module Hijacker
180
185
 
181
186
  # just calling establish_connection doesn't actually check to see if
182
187
  # we've established a VALID connection. a call to connection will check
183
- # this, and throw an error if the connection's invalid. It is important
188
+ # this, and throw an error if the connection's invalid. It is important
184
189
  # to catch the error and reconnect to a known valid database or rails
185
190
  # will get stuck. This is because once we establish a connection to an
186
191
  # invalid database, the next request will do a courteousy touch to the
@@ -200,14 +205,14 @@ private
200
205
  def self.determine_database(target_name, sister_name)
201
206
  if sister_name
202
207
  database = Hijacker::Database.find_by_name(sister_name)
203
- raise(Hijacker::InvalidDatabase, sister_name) if database.nil?
208
+ raise(Hijacker::InvalidDatabase.new(sister_name)) if database.nil?
204
209
  database
205
210
  elsif valid_routes[target_name]
206
211
  valid_routes[target_name] # cached valid database
207
212
  else
208
213
  database = Hijacker::Alias.find_by_name(target_name).try(:database) ||
209
214
  Hijacker::Database.find_by_name(target_name)
210
- raise(Hijacker::InvalidDatabase, target_name) if database.nil?
215
+ raise(Hijacker::InvalidDatabase.new(target_name)) if database.nil?
211
216
  database
212
217
  end
213
218
  end
@@ -1,16 +1,15 @@
1
+ # DEPRECATED: use middleware instead
1
2
  module Hijacker::ControllerMethods
2
3
  module Instance
3
4
  def hijack_connection
4
- host = request.host
5
-
6
- master, sister = determine_databases(host)
5
+ master, sister = determine_databases
7
6
 
8
7
  Hijacker.connect(master, sister)
9
-
8
+
10
9
  return true
11
10
  rescue Hijacker::InvalidDatabase => e
12
11
  render_invalid_db
13
-
12
+
14
13
  # If we've encountered a bad database connection, we don't want
15
14
  # to continue rendering the rest of the before_filters on this, which it will
16
15
  # try to do even when just rendering the bit of text above. If any filters
@@ -20,19 +19,8 @@ module Hijacker::ControllerMethods
20
19
 
21
20
  # Returns 2-member array of the main database to connect to, and the sister
22
21
  # (sister will be nil if no master is found, which means we are on the master).
23
- def determine_databases(host)
24
- if Hijacker.do_hijacking?
25
- Hijacker.config[:domain_patterns].find {|pattern| host =~ pattern}
26
- client = $1
27
- else # development, test, etc
28
- client = ActiveRecord::Base.configurations[Rails.env]['database']
29
- end
30
-
31
- raise Hijacker::UnparseableURL, "cannot parse '#{host}'" if client.nil?
32
-
33
- master, sister = Hijacker::Database.find_master_and_sister_for(client)
34
-
35
- return [master, sister]
22
+ def determine_databases
23
+ Hijacker::RequestParser.new(request.env).determine_databases
36
24
  end
37
25
 
38
26
  def render_invalid_db
@@ -51,7 +51,7 @@ class Hijacker::Database < ActiveRecord::Base
51
51
  def self.current
52
52
  find(:first, :conditions => {:database => Hijacker.current_client})
53
53
  end
54
-
54
+
55
55
  # returns a string or nil
56
56
  def self.find_master_for(client)
57
57
  @masters ||= {}
@@ -85,7 +85,7 @@ class Hijacker::Database < ActiveRecord::Base
85
85
  sites.delete(Hijacker.current_client)
86
86
  connect_each(sites, &block)
87
87
  end
88
-
88
+
89
89
  def self.find_shared_sites_for(client)
90
90
  @shared_sites ||= {}
91
91
  return @shared_sites[client] if @shared_sites[client].present?
@@ -1,18 +1,46 @@
1
1
  module Hijacker
2
2
  class Middleware
3
- def initialize(app)
3
+ HEADER_KEY = "HTTP_X_HIJACKER_DB".freeze
4
+ DEFAULT_NOT_FOUND = ->(database, env) {
5
+ [404, {}, ["Database #{database} not found"]]
6
+ }
7
+ DEFAULT_BAD_URL = ->(message, env) {
8
+ [404, {}, [message]]
9
+ }
10
+
11
+ attr_reader :not_found, :bad_url
12
+
13
+ def initialize(app, options = {})
14
+ options = options.dup
4
15
  @app = app
16
+ @not_found = options.delete(:not_found) || DEFAULT_NOT_FOUND
17
+ @bad_url = options.delete(:bad_url) || DEFAULT_BAD_URL
18
+
19
+ unless options.blank?
20
+ raise "Unknown Hijacker::Middleware options #{options.keys.join(",")}"
21
+ end
5
22
  end
6
23
 
7
24
  def call(env)
8
- if env['HTTP_X_HIJACKER_DB'].present?
9
- begin
10
- Hijacker.connect(env['HTTP_X_HIJACKER_DB'])
11
- rescue Hijacker::InvalidDatabase => e
12
- return [404, {}, ""]
13
- end
25
+ begin
26
+ Hijacker.connect(*determine_databases(env))
27
+ rescue Hijacker::InvalidDatabase => e
28
+ return not_found.call(e.database, env)
29
+ rescue Hijacker::UnparseableURL => e
30
+ return bad_url.call(e.message, env)
14
31
  end
32
+
15
33
  @app.call(env)
16
34
  end
35
+
36
+ private
37
+
38
+ def determine_databases(env)
39
+ if client = env[HEADER_KEY]
40
+ Hijacker::Database.find_master_and_sister_for(client)
41
+ else
42
+ RequestParser.new(env).determine_databases
43
+ end
44
+ end
17
45
  end
18
46
  end
@@ -18,7 +18,7 @@ module Hijacker
18
18
  it "requires a host" do
19
19
  subject.host = nil
20
20
  subject.should_not be_valid
21
- subject.errors.on(:host_id).should == "can't be blank"
21
+ subject.errors[:host_id].should == ["can't be blank"]
22
22
 
23
23
  subject.host = host
24
24
  subject.should be_valid
@@ -38,12 +38,12 @@ module Hijacker
38
38
 
39
39
  describe "#connect_each" do
40
40
  def db(name)
41
- mock("#{name}_db", :database => name)
41
+ double("#{name}_db", :database => name)
42
42
  end
43
43
 
44
44
  before (:each) do
45
- Database.stub!(:all).and_return([ db("one"), db("two"), db("three") ])
46
- Hijacker.stub!(:connect)
45
+ Database.stub(:all).and_return([ db("one"), db("two"), db("three") ])
46
+ Hijacker.stub(:connect)
47
47
  end
48
48
 
49
49
  it "Calls the block once for each database" do
@@ -71,10 +71,10 @@ module Hijacker
71
71
  end
72
72
 
73
73
  it "eats invalid database errors" do
74
- Hijacker.stub(:connect).and_raise(Hijacker::InvalidDatabase)
74
+ Hijacker.stub(:connect).and_raise(Hijacker::InvalidDatabase.new("doesntmatter"))
75
75
  expect { Database.connect_each {|db| } }.not_to raise_error
76
76
  end
77
-
77
+
78
78
  it "eats mysql-specific errors for missing databases" do
79
79
  [Mysql::Error, Mysql2::Error].each do |klass|
80
80
  exception = klass.new("Unknown database 'fake'")
@@ -4,11 +4,11 @@ describe Hijacker::Host do
4
4
  it "validates the format of the hostname" do
5
5
  subject.hostname = "lol nope"
6
6
  subject.should_not be_valid
7
- subject.errors.on(:hostname).should == "is invalid"
7
+ subject.errors[:hostname].should == ["is invalid"]
8
8
 
9
9
  subject.hostname = nil
10
10
  subject.should_not be_valid
11
- subject.errors.on(:hostname).should == "is invalid"
11
+ subject.errors[:hostname].should == ["is invalid"]
12
12
 
13
13
  subject.hostname = "db-01.example.com"
14
14
  subject.should be_valid
@@ -14,18 +14,130 @@ module Hijacker
14
14
  end
15
15
  end
16
16
 
17
+ let!(:host) { Hijacker::Host.create!(:hostname => "localhost") }
18
+ let!(:master) { Hijacker::Database.create!(:database => "sample-db", :host => host) }
19
+ let!(:foo) { Hijacker::Database.create!(:database => "foo", :host => host) }
20
+
21
+ before(:each) do
22
+ Hijacker.config = {
23
+ :hosted_environments => %w[test],
24
+ :domain_patterns => [
25
+ /^(.+)-admin\.crystalcommerce\.com/
26
+ ],
27
+ :sister_site_models => []
28
+ }
29
+
30
+ ActiveRecord::Base.stub(:establish_connection)
31
+ end
32
+
17
33
  describe "#call" do
34
+ let(:request_env) {{ 'HTTP_X_HIJACKER_DB' => 'sample-db' }}
35
+
36
+ def make_request
37
+ get '/', {}, request_env
38
+ end
39
+
18
40
  context "When the 'X-Hijacker-DB' header is set" do
19
41
  it "connects to the database from the header" do
20
- Hijacker.should_receive(:connect).with("sample-db")
21
- get '/',{}, 'HTTP_X_HIJACKER_DB' => 'sample-db'
42
+ make_request
43
+ expect(Hijacker.current_client).to eq('sample-db')
44
+ end
45
+
46
+ it "passes through" do
47
+ resp = make_request
48
+ expect(resp.status).to eq(200)
49
+ expect(resp.headers['blah']).to eq("blah")
50
+ expect(resp.body).to eq("success")
22
51
  end
23
52
  end
24
53
 
25
54
  context "When the 'X-Hijacker-DB' header is not set" do
26
- it "doesn't connect to any database" do
27
- Hijacker.should_not_receive(:connect)
28
- get '/',{}, "x-not-db-header" => "something"
55
+ let(:request_env) do
56
+ {
57
+ "HTTP_HOST" => "foo-admin.crystalcommerce.com"
58
+ }
59
+ end
60
+
61
+ it "parses the host from the request and connects" do
62
+ make_request
63
+ expect(Hijacker.current_client).to eq("foo")
64
+ end
65
+
66
+ it "passes through" do
67
+ resp = make_request
68
+ expect(resp.status).to eq(200)
69
+ expect(resp.headers['blah']).to eq("blah")
70
+ expect(resp.body).to eq("success")
71
+ end
72
+
73
+
74
+ context "databases could not be determined" do
75
+ let(:request_env) do
76
+ {
77
+ "HTTP_HOST" => "bogus-admin.crystalcommerce.com"
78
+ }
79
+ end
80
+
81
+ it "returns a 404" do
82
+ resp = make_request
83
+ expect(resp.status).to eq(404)
84
+ expect(resp.body).to eq("Database bogus not found")
85
+ end
86
+ end
87
+ end
88
+
89
+ context "unparseable URL" do
90
+ let(:request_env) do
91
+ {
92
+ "HTTP_HOST" => "(>'-'>)"
93
+ }
94
+ end
95
+
96
+ it "returns a 404" do
97
+ resp = make_request
98
+ expect(resp.status).to eq(404)
99
+ expect(resp.body).to eq("cannot parse '(>'-'>)'")
100
+ end
101
+
102
+ context "custom bad url handler" do
103
+ def app
104
+ Rack::Builder.new do
105
+ use Hijacker::Middleware, :bad_url => ->(message, env) { [404, {}, "You done goofed, #{message}"]}
106
+ run lambda { |env| [200, { 'blah' => 'blah' }, ["success"]] }
107
+ end
108
+ end
109
+
110
+ it "uses the custom not found handler" do
111
+ resp = make_request
112
+ expect(resp.status).to eq(404)
113
+ expect(resp.body).to eq("You done goofed, cannot parse '(>'-'>)'")
114
+ end
115
+ end
116
+ end
117
+
118
+ context "database not found" do
119
+ let(:request_env) {{ 'HTTP_X_HIJACKER_DB' => 'bogus' }}
120
+
121
+ it "returns a 404" do
122
+ resp = make_request
123
+ expect(resp.status).to eq(404)
124
+ expect(resp.body).to eq("Database bogus not found")
125
+ end
126
+
127
+
128
+ context "custom missing database handler" do
129
+ def app
130
+ Rack::Builder.new do
131
+ use Hijacker::Middleware, :not_found => ->(database, env) { [404, {}, "You done goofed, #{database}"]}
132
+ run lambda { |env| [200, { 'blah' => 'blah' }, ["success"]] }
133
+ end
134
+ end
135
+
136
+ it "uses the custom not found handler" do
137
+ resp = make_request
138
+ expect(resp.status).to eq(404)
139
+ expect(resp.body).to eq("You done goofed, bogus")
140
+ end
29
141
  end
30
142
  end
31
143
  end
@@ -6,7 +6,7 @@ describe Hijacker do
6
6
  before(:each) do
7
7
  Hijacker.config = {
8
8
  :hosted_environments => hosted_environments
9
- }
9
+ }
10
10
  end
11
11
 
12
12
  let!(:host) { Hijacker::Host.create!(:hostname => "localhost") }
@@ -32,7 +32,7 @@ describe Hijacker do
32
32
  end
33
33
  end
34
34
 
35
- describe "class methods" do
35
+ describe "class methods" do
36
36
  subject { Hijacker }
37
37
 
38
38
  describe ".connect" do
@@ -43,7 +43,7 @@ describe Hijacker do
43
43
  subject.sister = nil
44
44
  subject.valid_routes = {}
45
45
  ActiveRecord::Base.stub(:establish_connection)
46
- subject.stub(:root_connection).and_return(stub(:config => {}))
46
+ subject.stub(:root_connection).and_return(double(:config => {}))
47
47
  subject.stub(:connect_sister_site_models)
48
48
  Hijacker.stub(:do_hijacking?).and_return(true)
49
49
  ::ActionController::Base.stub(:perform_caching).
@@ -149,7 +149,7 @@ describe Hijacker do
149
149
 
150
150
  it "enables the query cache on ActiveRecord::Base" do
151
151
  subject.connect('master_db')
152
- ::ActiveRecord::Base.connection.query_cache_enabled.should be_true
152
+ ::ActiveRecord::Base.connection.query_cache_enabled.should eq(true)
153
153
  end
154
154
 
155
155
  it "calls cache on the connection" do
@@ -159,7 +159,7 @@ describe Hijacker do
159
159
  end
160
160
 
161
161
  context "after_hijack call specified" do
162
- let(:spy) { stub.as_null_object }
162
+ let(:spy) { double.as_null_object }
163
163
  before(:each) do
164
164
  Hijacker.config.merge!(:after_hijack => spy)
165
165
  end
data/spec/spec_helper.rb CHANGED
@@ -19,7 +19,7 @@ ActiveRecord::Base.configurations = {
19
19
  }
20
20
  }
21
21
 
22
- ActiveRecord::Base.establish_connection
22
+ ActiveRecord::Base.establish_connection(:test)
23
23
  require File.dirname(__FILE__) + "/../example_root_schema"
24
24
 
25
25
  require 'hijacker'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbhijacker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Xavier
@@ -10,104 +10,166 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-03-21 00:00:00.000000000 Z
13
+ date: 2014-06-18 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
- - - '>='
19
+ - - ">="
20
20
  - !ruby/object:Gem::Version
21
21
  version: 2.3.14
22
+ - - "<"
23
+ - !ruby/object:Gem::Version
24
+ version: '4.0'
22
25
  type: :runtime
23
26
  prerelease: false
24
27
  version_requirements: !ruby/object:Gem::Requirement
25
28
  requirements:
26
- - - '>='
29
+ - - ">="
27
30
  - !ruby/object:Gem::Version
28
31
  version: 2.3.14
32
+ - - "<"
33
+ - !ruby/object:Gem::Version
34
+ version: '4.0'
35
+ - !ruby/object:Gem::Dependency
36
+ name: jeweler
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ type: :development
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
29
49
  - !ruby/object:Gem::Dependency
30
50
  name: bundler
31
51
  requirement: !ruby/object:Gem::Requirement
32
52
  requirements:
33
- - - '>='
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: guard
65
+ requirement: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
34
68
  - !ruby/object:Gem::Version
35
- version: '1.3'
69
+ version: '0'
36
70
  type: :development
37
71
  prerelease: false
38
72
  version_requirements: !ruby/object:Gem::Requirement
39
73
  requirements:
40
- - - '>='
74
+ - - ">="
41
75
  - !ruby/object:Gem::Version
42
- version: '1.3'
76
+ version: '0'
77
+ - !ruby/object:Gem::Dependency
78
+ name: guard-rspec
79
+ requirement: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ type: :development
85
+ prerelease: false
86
+ version_requirements: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ - !ruby/object:Gem::Dependency
92
+ name: guard-bundler
93
+ requirement: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ type: :development
99
+ prerelease: false
100
+ version_requirements: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
43
105
  - !ruby/object:Gem::Dependency
44
106
  name: rake
45
107
  requirement: !ruby/object:Gem::Requirement
46
108
  requirements:
47
- - - '>='
109
+ - - ">="
48
110
  - !ruby/object:Gem::Version
49
111
  version: 0.9.2
50
112
  type: :development
51
113
  prerelease: false
52
114
  version_requirements: !ruby/object:Gem::Requirement
53
115
  requirements:
54
- - - '>='
116
+ - - ">="
55
117
  - !ruby/object:Gem::Version
56
118
  version: 0.9.2
57
119
  - !ruby/object:Gem::Dependency
58
120
  name: rack-test
59
121
  requirement: !ruby/object:Gem::Requirement
60
122
  requirements:
61
- - - '>='
123
+ - - ">="
62
124
  - !ruby/object:Gem::Version
63
125
  version: 0.6.1
64
126
  type: :development
65
127
  prerelease: false
66
128
  version_requirements: !ruby/object:Gem::Requirement
67
129
  requirements:
68
- - - '>='
130
+ - - ">="
69
131
  - !ruby/object:Gem::Version
70
132
  version: 0.6.1
71
133
  - !ruby/object:Gem::Dependency
72
134
  name: rack
73
135
  requirement: !ruby/object:Gem::Requirement
74
136
  requirements:
75
- - - '>='
137
+ - - ">="
76
138
  - !ruby/object:Gem::Version
77
139
  version: 1.1.0
78
140
  type: :development
79
141
  prerelease: false
80
142
  version_requirements: !ruby/object:Gem::Requirement
81
143
  requirements:
82
- - - '>='
144
+ - - ">="
83
145
  - !ruby/object:Gem::Version
84
146
  version: 1.1.0
85
147
  - !ruby/object:Gem::Dependency
86
148
  name: rspec
87
149
  requirement: !ruby/object:Gem::Requirement
88
150
  requirements:
89
- - - '>='
151
+ - - "~>"
90
152
  - !ruby/object:Gem::Version
91
153
  version: '2.8'
92
154
  type: :development
93
155
  prerelease: false
94
156
  version_requirements: !ruby/object:Gem::Requirement
95
157
  requirements:
96
- - - '>='
158
+ - - "~>"
97
159
  - !ruby/object:Gem::Version
98
160
  version: '2.8'
99
161
  - !ruby/object:Gem::Dependency
100
162
  name: sqlite3
101
163
  requirement: !ruby/object:Gem::Requirement
102
164
  requirements:
103
- - - '>='
165
+ - - "~>"
104
166
  - !ruby/object:Gem::Version
105
167
  version: 1.3.5
106
168
  type: :development
107
169
  prerelease: false
108
170
  version_requirements: !ruby/object:Gem::Requirement
109
171
  requirements:
110
- - - '>='
172
+ - - "~>"
111
173
  - !ruby/object:Gem::Version
112
174
  version: 1.3.5
113
175
  description: Allows a single Rails appliation to access many different databases
@@ -122,8 +184,8 @@ files:
122
184
  - MIT-LICENSE
123
185
  - README.rdoc
124
186
  - Rakefile
125
- - example_root_schema.rb
126
187
  - dbhijacker.gemspec
188
+ - example_root_schema.rb
127
189
  - lib/dbhijacker.rb
128
190
  - lib/hijacker.rb
129
191
  - lib/hijacker/active_record_ext.rb
@@ -145,22 +207,22 @@ licenses:
145
207
  metadata: {}
146
208
  post_install_message:
147
209
  rdoc_options:
148
- - --charset=UTF-8
210
+ - "--charset=UTF-8"
149
211
  require_paths:
150
212
  - lib
151
213
  required_ruby_version: !ruby/object:Gem::Requirement
152
214
  requirements:
153
- - - '>='
215
+ - - ">="
154
216
  - !ruby/object:Gem::Version
155
217
  version: '0'
156
218
  required_rubygems_version: !ruby/object:Gem::Requirement
157
219
  requirements:
158
- - - '>='
220
+ - - ">="
159
221
  - !ruby/object:Gem::Version
160
222
  version: '0'
161
223
  requirements: []
162
224
  rubyforge_project:
163
- rubygems_version: 2.0.3
225
+ rubygems_version: 2.2.2
164
226
  signing_key:
165
227
  specification_version: 4
166
228
  summary: One application, multiple client databases