dbhijacker 0.9.2 → 0.10.0

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