activerecord_url_connections 0.0.2 → 0.0.3

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.
data/Gemfile CHANGED
@@ -1,5 +1,10 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "rake", "0.8.7"
3
+ gem "rake"
4
4
  # Specify your gem's dependencies in activerecord_url_connections.gemspec
5
5
  gemspec
6
+
7
+ group :test do
8
+ gem "ruby-debug19", :require => "ruby-debug"
9
+ gem "mocha", :require => nil
10
+ end
data/Rakefile CHANGED
@@ -1,2 +1,14 @@
1
- require 'bundler'
1
+ require "bundler"
2
+ require "rake"
3
+ require "rake/testtask"
4
+ module ActiveRecordURLConnections
5
+ class RakeTasks
6
+ include Rake::DSL
7
+ Rake::TestTask.new do |t|
8
+ t.libs << "test"
9
+ t.test_files = FileList["test/*_test.rb"]
10
+ t.verbose = true
11
+ end
12
+ end
13
+ end
2
14
  Bundler::GemHelper.install_tasks
data/Readme.md ADDED
@@ -0,0 +1,68 @@
1
+ # ActiveRecord URL Connections
2
+
3
+ This gem adds support to ActiveRecord for connecting to a database by
4
+ specifying a URL rather than a hash of parameters. Many ruby adapters
5
+ have opted for this format (DataMapper, Sequel, MongoDB, etc.) in
6
+ addition to numerous alternatives in other languages. So why should AR
7
+ be missing out on all the fun?
8
+
9
+ The other notable benefit is that you can continue to use
10
+ `config/database.yml` in development, while setting an ENV variable
11
+ of `DATABASE_URL` on your production server to specify the connection
12
+ settings. No more risk of committing sensitive database credentials into
13
+ version control, or having to worry about Capistrano moving the relevant
14
+ production file into place on deploy.
15
+
16
+ ## Usage
17
+
18
+ The URL takes the form of:
19
+
20
+ <adapter>://<user>:<password>@<hostname>:<port>/<database>?<options>
21
+
22
+ Where options is a query string of key value pairs. For example:
23
+
24
+ mysql://app:s3crets@127.0.0.1:5123/nyancat_production?encoding=utf8
25
+
26
+ Only `adapter`, `hostname`, and `database` are required. Everything else
27
+ is optional, so to connect using local user permissions in postgres just do:
28
+
29
+ postgres://localhost/nyancat_production
30
+
31
+ ## Installation
32
+
33
+ Either in your `Gemfile`:
34
+
35
+ gem "activerecord_url_connections"
36
+
37
+ Or install it directly onto your system with rubygems:
38
+
39
+ gem install activerecord_url_connections
40
+
41
+ Then require in your app:
42
+
43
+ require "activerecord_url_connections"
44
+
45
+ ## License
46
+
47
+ ActiveRecord URL Connections is MIT Licensed
48
+
49
+ Copyright (C) 2011 by Glenn Gillen
50
+
51
+ Permission is hereby granted, free of charge, to any person obtaining a copy
52
+ of this software and associated documentation files (the "Software"), to deal
53
+ in the Software without restriction, including without limitation the rights
54
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
55
+ copies of the Software, and to permit persons to whom the Software is
56
+ furnished to do so, subject to the following conditions:
57
+
58
+ The above copyright notice and this permission notice shall be included in
59
+ all copies or substantial portions of the Software.
60
+
61
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
62
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
63
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
64
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
65
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
66
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
67
+ SOFTWARE.
68
+
@@ -16,4 +16,5 @@ Gem::Specification.new do |s|
16
16
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
18
  s.require_paths = ["lib"]
19
+ s.add_dependency('activerecord')
19
20
  end
@@ -1,3 +1,4 @@
1
+ require "active_record"
1
2
  module ActiveRecordURLConnections
2
3
  def self.parse(str)
3
4
  config = URI.parse(str)
@@ -11,3 +12,33 @@ module ActiveRecordURLConnections
11
12
  }
12
13
  end
13
14
  end
15
+
16
+ ActiveRecord::Base.class_eval do
17
+ class << self
18
+ alias_method :establish_connection_without_url, :establish_connection
19
+ def establish_connection(spec = nil)
20
+ spec ||= ENV["DATABASE_URL"]
21
+ if spec.is_a?(String) && url = URI.parse(spec)
22
+ adapter = url.scheme
23
+ adapter = "postgresql" if adapter == "postgres"
24
+ spec = { :adapter => adapter,
25
+ :username => url.user,
26
+ :password => url.password,
27
+ :database => url.path.sub(%r{^/},""),
28
+ :port => url.port,
29
+ :hostname => url.host }
30
+ spec.reject!{ |key,value| value.nil? }
31
+ spec.merge!(split_query_options(url.query))
32
+ end
33
+ establish_connection_without_url(spec)
34
+ rescue URI::InvalidURIError
35
+ establish_connection_without_url(spec)
36
+ end
37
+
38
+ private
39
+ def split_query_options(query = nil)
40
+ return {} unless query
41
+ Hash[query.split("&").map{ |pair| pair.split("=") }].symbolize_keys
42
+ end
43
+ end
44
+ end
@@ -1,3 +1,3 @@
1
1
  module ActiveRecordURLConnections
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -0,0 +1,93 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ Bundler.require(:test)
4
+ require "test/unit"
5
+ require "mocha"
6
+ require "activerecord_url_connections"
7
+ class TestConnection < Test::Unit::TestCase
8
+ def mock_connection_spec(spec, adapter)
9
+ conn_spec = ActiveRecord::Base::ConnectionSpecification.new(spec, adapter)
10
+ ActiveRecord::Base::ConnectionSpecification.stubs(:new).
11
+ with(spec, adapter).returns(conn_spec)
12
+ conn_spec
13
+ end
14
+
15
+ def setup
16
+ ActiveRecord::ConnectionAdapters::ConnectionHandler.any_instance.
17
+ stubs(:establish_connection)
18
+ end
19
+
20
+ def spec_hash(opts = {})
21
+ default_spec = { :adapter => "mysql",
22
+ :username => "user",
23
+ :password => "secret",
24
+ :hostname => "localhost",
25
+ :database => "mydatabase" }
26
+ default_spec.merge!(opts)
27
+ default_spec
28
+ end
29
+
30
+ def test_generic_url_connection
31
+ connection_spec = mock_connection_spec(spec_hash, "mysql_connection")
32
+ url = "mysql://user:secret@localhost/mydatabase"
33
+ ActiveRecord::ConnectionAdapters::ConnectionHandler.any_instance.
34
+ expects(:establish_connection).with("ActiveRecord::Base", connection_spec)
35
+ ActiveRecord::Base.establish_connection(url)
36
+ end
37
+
38
+ def test_works_with_traditional_hash_spec
39
+ spec = spec_hash
40
+ connection_spec = mock_connection_spec(spec, "mysql_connection")
41
+ ActiveRecord::ConnectionAdapters::ConnectionHandler.any_instance.
42
+ expects(:establish_connection).with("ActiveRecord::Base", connection_spec)
43
+ ActiveRecord::Base.establish_connection(spec)
44
+ end
45
+
46
+ def test_doesnt_raise_uri_parse_error
47
+ url = "this isn't a URL"
48
+ assert_raises ActiveRecord::AdapterNotSpecified do
49
+ ActiveRecord::Base.establish_connection(url)
50
+ end
51
+ end
52
+
53
+ def test_translates_postgres
54
+ spec = spec_hash(:adapter => "postgresql")
55
+ connection_spec = mock_connection_spec(spec, "postgresql_connection")
56
+ url = "postgres://user:secret@localhost/mydatabase"
57
+ ActiveRecord::ConnectionAdapters::ConnectionHandler.any_instance.
58
+ expects(:establish_connection).with("ActiveRecord::Base", connection_spec)
59
+ ActiveRecord::Base.establish_connection(url)
60
+ end
61
+
62
+ def test_supports_additional_options_as_params
63
+ spec = spec_hash(:encoding => "utf8",
64
+ :hostname => "remotehost.example.org",
65
+ :port => 3133,
66
+ :random_key => "blah")
67
+ connection_spec = mock_connection_spec(spec, "mysql_connection")
68
+ url = "mysql://user:secret@remotehost.example.org:3133/mydatabase?encoding=utf8&random_key=blah"
69
+ ActiveRecord::ConnectionAdapters::ConnectionHandler.any_instance.
70
+ expects(:establish_connection).with("ActiveRecord::Base", connection_spec)
71
+ ActiveRecord::Base.establish_connection(url)
72
+ end
73
+
74
+ def test_drops_empty_values_from_spec
75
+ spec = spec_hash
76
+ spec.delete(:username)
77
+ spec.delete(:password)
78
+ connection_spec = mock_connection_spec(spec, "mysql_connection")
79
+ url = "mysql://localhost/mydatabase"
80
+ ActiveRecord::ConnectionAdapters::ConnectionHandler.any_instance.
81
+ expects(:establish_connection).with("ActiveRecord::Base", connection_spec)
82
+ ActiveRecord::Base.establish_connection(url)
83
+ end
84
+
85
+ def test_use_environment_variable_if_no_spec_provided
86
+ url = "mysql://user:secret@localhost/mydatabase"
87
+ ENV["DATABASE_URL"] = url
88
+ connection_spec = mock_connection_spec(spec_hash, "mysql_connection")
89
+ ActiveRecord::ConnectionAdapters::ConnectionHandler.any_instance.
90
+ expects(:establish_connection).with("ActiveRecord::Base", connection_spec)
91
+ ActiveRecord::Base.establish_connection
92
+ end
93
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: activerecord_url_connections
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.2
5
+ version: 0.0.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - Glenn Gillen
@@ -10,10 +10,20 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-06-01 00:00:00 +01:00
13
+ date: 2011-06-28 00:00:00 +01:00
14
14
  default_executable:
15
- dependencies: []
16
-
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: activerecord
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :runtime
26
+ version_requirements: *id001
17
27
  description: Allows database connections to be defined as URLS, then converted to hash for use in ActiveRecord
18
28
  email:
19
29
  - glenn@rubypond.com
@@ -27,9 +37,11 @@ files:
27
37
  - .gitignore
28
38
  - Gemfile
29
39
  - Rakefile
40
+ - Readme.md
30
41
  - activerecord_url_connections.gemspec
31
42
  - lib/activerecord_url_connections.rb
32
43
  - lib/activerecord_url_connections/version.rb
44
+ - test/connection_test.rb
33
45
  has_rdoc: true
34
46
  homepage: ""
35
47
  licenses: []
@@ -44,18 +56,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
44
56
  requirements:
45
57
  - - ">="
46
58
  - !ruby/object:Gem::Version
47
- hash: -2816335097435414650
48
- segments:
49
- - 0
50
59
  version: "0"
51
60
  required_rubygems_version: !ruby/object:Gem::Requirement
52
61
  none: false
53
62
  requirements:
54
63
  - - ">="
55
64
  - !ruby/object:Gem::Version
56
- hash: -2816335097435414650
57
- segments:
58
- - 0
59
65
  version: "0"
60
66
  requirements: []
61
67
 
@@ -64,5 +70,5 @@ rubygems_version: 1.6.0
64
70
  signing_key:
65
71
  specification_version: 3
66
72
  summary: Convert URLs into AR friendly hashes
67
- test_files: []
68
-
73
+ test_files:
74
+ - test/connection_test.rb