sequelizer 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6628c636f7aee3fc9ffc3c36b9877167756c2cc0
4
+ data.tar.gz: b24750aba87b1a882ee81dd18d0ec078deab4e9c
5
+ SHA512:
6
+ metadata.gz: 986d3122766c0f9cac14bba4196469edc93d4c32718a716ae93e823898a84b35d7117d8c70d341f203c98d850cd83ceaa5867e57dab45ff5682e5a01bb405eec
7
+ data.tar.gz: cd2f304548d984e8d4229350bee9b8328f2bc7193b30c4b73c4d14c2dc90bc3a955d8349855b45c8f3eadd291a613f7b587efaf9446e6220ba9fa64490df9fa4
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sequelizer.gemspec
4
+ gemspec
@@ -0,0 +1,28 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :minitest do
5
+ # with Minitest::Unit
6
+ watch(%r{^test/(.*)\/?test_(.*)\.rb$})
7
+ watch(%r{^lib/(.*/)?([^/]+)\.rb$}) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
8
+ watch(%r{^test/test_helper\.rb$}) { 'test' }
9
+
10
+ # with Minitest::Spec
11
+ # watch(%r{^spec/(.*)_spec\.rb$})
12
+ # watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
13
+ # watch(%r{^spec/spec_helper\.rb$}) { 'spec' }
14
+
15
+ # Rails 4
16
+ # watch(%r{^app/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
17
+ # watch(%r{^app/controllers/application_controller\.rb$}) { 'test/controllers' }
18
+ # watch(%r{^app/controllers/(.+)_controller\.rb$}) { |m| "test/integration/#{m[1]}_test.rb" }
19
+ # watch(%r{^app/views/(.+)_mailer/.+}) { |m| "test/mailers/#{m[1]}_mailer_test.rb" }
20
+ # watch(%r{^lib/(.+)\.rb$}) { |m| "test/lib/#{m[1]}_test.rb" }
21
+ # watch(%r{^test/.+_test\.rb$})
22
+ # watch(%r{^test/test_helper\.rb$}) { 'test' }
23
+
24
+ # Rails < 4
25
+ # watch(%r{^app/controllers/(.*)\.rb$}) { |m| "test/functional/#{m[1]}_test.rb" }
26
+ # watch(%r{^app/helpers/(.*)\.rb$}) { |m| "test/helpers/#{m[1]}_test.rb" }
27
+ # watch(%r{^app/models/(.*)\.rb$}) { |m| "test/unit/#{m[1]}_test.rb" }
28
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Outcomes Insights, Inc.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,78 @@
1
+ # Sequelizer
2
+
3
+ I was tired of writing the code to bootstrap a connection to my databases.
4
+
5
+ [Sequel](https://github.com/jeremyevans/sequel/) provides an easy mechanism for connecting to a database, but I didn't want to store my username/password/other sensitive information in the scripts I was writing.
6
+
7
+ So I wrote this gem that lets me store my database configuration options in either config/database.yml or .env and then lets me call `db` to get a connection to my database.
8
+
9
+ I normally use this gem when I'm writing a quick script or a Thor-based command line utility.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ gem 'sequelizer'
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install sequelizer
24
+
25
+ ## Usage
26
+
27
+ To get the most out of Sequelizer, you'll need to create a config/database.yml file or a .env file and specify your database configuration options in that file.
28
+
29
+ You'll also need to make sure the gem for your database is installed. You can do this by adding a the gem to your application's Gemfile.
30
+
31
+ Sequelizer comes with a handy command that will update your Gemfile for you. Once you've specified your database configuration, run `bundle exec sequelizer update_gemfile`. The command will look up the right gem to use with the adapter you've specified, add a line to your Gemfile specifying that gem, and run `bundle install` to install the gem for you.
32
+
33
+ Once you've specified your options and made sure your database's gem is installed, simply include the Sequelizer module in any class that needs a database connection and you'll get two handy-dandy methods: `db` and `new_db`
34
+
35
+ Observe:
36
+ ```ruby
37
+ require 'sequelizer'
38
+
39
+ class ClassThatNeedsSomeDBLove
40
+ include Sequelizer
41
+
42
+ def my_super_cool_method_that_needs_to_talk_to_a_db
43
+ db[:my_awesome_table].join(
44
+ db[:another_great_table].select(:an_important_column),
45
+ [:an_important_column])
46
+ end
47
+ end
48
+ ```
49
+
50
+ `db` will create a new connection to the database and cache that connection so that subsequent calls to `db` will use the same connection.
51
+
52
+ `new_db` will create a new connection to the database on each call.
53
+
54
+ Both take a hash of database options if you don't want to create a config/database.yml or .env file, or simply wish to override those options. The options you pass in aren't merged against any other configuration files you might have set up.
55
+
56
+ Take a look at the examples directory for a few ways you can specify your database configuration options.
57
+
58
+ ## Frustrations
59
+
60
+ I can't seem to figure out a way to avoid having to specify the database gem in the a user's bundler file. If anyone has ideas on how to automagically load the correct database gem based on the database options fed to Sequelizer, please let me know!
61
+
62
+ ## Contributing
63
+
64
+ 1. Fork it ( http://github.com/outcomesinsights/sequelizer/fork )
65
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
66
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
67
+ 4. Push to the branch (`git push origin my-new-feature`)
68
+ 5. Create new Pull Request
69
+
70
+ ## Thanks
71
+
72
+ - [Outcomes Insights, Inc.](http://outins.com)
73
+ - Many thanks for allowing me to release a portion of my work as Open Source Software!
74
+ - Jeremy Evans
75
+ - For writing Sequel!
76
+
77
+ ## License
78
+ Released under the MIT license, Copyright (c) 2014 Outcomes Insights, Inc.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/sequelizer/cli'
4
+
5
+ Sequelizer::CLI.start(ARGV)
@@ -0,0 +1,15 @@
1
+ # A normal database.yml file contains a file with many different database
2
+ # configurations specified, one for each "environment".
3
+ #
4
+ # This is a Rails convention, but frankly, most of the time I have a single
5
+ # environment in my one-off scripts and don't want to bother with specifying
6
+ # different environments.
7
+ #
8
+ # So I can just define my database options like so:
9
+ ---
10
+ adapter: postgres # Note: postgresql also works, but Sequel prefers postgres
11
+ database: my_database
12
+ host: localhost
13
+ username: my_user
14
+ password: my_great_password
15
+
@@ -0,0 +1,30 @@
1
+ # An example of a database.yml file that is very much like the kind we'd
2
+ # find in a Rails app.
3
+ #
4
+ # There are three environments defined.
5
+ #
6
+ # Sequelizer will look for which environment to use by reading the contents
7
+ # of your environment variables in the following order:
8
+ # SEQUELIZER_ENV
9
+ # RAILS_ENV
10
+ # RACK_ENV
11
+ #
12
+ # If all of those are nil, we'll default to development
13
+ common: &common
14
+ adapter: postgresql
15
+ host: localhost
16
+ username: my_username
17
+ password: my_password
18
+ schema_search_path: list,of,schemas
19
+
20
+ development:
21
+ <<: *common
22
+ database: dev_database
23
+
24
+ test:
25
+ adapter: sqlite
26
+ database: test.sqlite
27
+
28
+ production:
29
+ <<: *common
30
+ database: production_database
@@ -0,0 +1,10 @@
1
+ # Normally you'd name this file '.env' and place it in
2
+ # the root of your project's directoryo
3
+ #
4
+ # Then you'd specify your database options like so:
5
+ SEQUELIZER_ADAPTER=postgres
6
+ SEQUELIZER_USERNAME=my_username
7
+ SEQUELIZER_PASSWORD=super_secret_password
8
+ SEQUELIZER_DATABASE=name_of_database
9
+ SEQUELIZER_HOST=localhost
10
+ SEQUELIZER_SEARCH_PATH=list,of,schemas
@@ -0,0 +1,31 @@
1
+ require 'sequelizer/version'
2
+ require 'sequelizer/connection_maker'
3
+
4
+ # Include this module in any class where you'd like to quickly establish
5
+ # a Sequel connection to a database.
6
+ module Sequelizer
7
+ # Instantiates and memoizes a database connection. The +db+ method instantiates
8
+ # the connection on the first call and then memoizes itself so only a single
9
+ # connection is used on repeated calls
10
+ #
11
+ # options :: an optional set of database connection options.
12
+ # If no options are provided, options are read from
13
+ # config/database.yml or from .env or from environment variables.
14
+ def db(options = nil)
15
+ @_sequelizer_db ||= new_db(options)
16
+ end
17
+
18
+ # Instantiates and returns a new database connection on each call.
19
+ #
20
+ # options :: an optional set of database connection options.
21
+ # If no options are provided, options are read from
22
+ # config/database.yml or from .env or from environment variables.
23
+ def new_db(options = nil)
24
+ cm = ConnectionMaker.new(options)
25
+ conn = cm.connection
26
+ conn.define_singleton_method(:sequelizer_options) do
27
+ cm.options
28
+ end
29
+ conn
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ require 'thor'
2
+ require_relative 'gemfile_modifier'
3
+
4
+ module Sequelizer
5
+ class CLI < Thor
6
+ desc 'update_gemfile', 'adds or replaces a line in your Gemfile to include the correct database adapter to work with Sequel'
7
+ option 'dry-run', type: :boolean, desc: 'Only prints out what it would do, but makes no changes'
8
+ option 'skip-bundle', type: :boolean, desc: "Don't run `bundle install` after modifying Gemfile"
9
+ def update_gemfile
10
+ GemfileModifier.new(options).modify
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ require 'sequel'
2
+ require_relative 'options'
3
+
4
+ module Sequelizer
5
+ # Class that handles loading/interpretting the database options and
6
+ # creates the Sequel connection
7
+ class ConnectionMaker
8
+ # The options for Sequel.connect
9
+ attr :options
10
+
11
+ # Accepts an optional set of database options
12
+ #
13
+ # If no options are provided, attempts to read options from
14
+ # config/database.yml
15
+ #
16
+ # If config/database.yml doesn't exist, Dotenv is used to try to load a
17
+ # .env file, then uses any SEQUELIZER_* environment variables as
18
+ # database options
19
+ def initialize(options = nil)
20
+ @options = Options.new(options)
21
+ end
22
+
23
+ # Returns a Sequel connection to the database
24
+ def connection
25
+ Sequel.connect(options.to_hash)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ require 'dotenv'
2
+
3
+ module Sequelizer
4
+ # Creates a set of database configuration options from environment
5
+ # variables
6
+ class EnvConfig
7
+ # Any environment variables in the .env file are loaded and then
8
+ # any environment variable starting with SEQUELIZER_ will be used
9
+ # as an option for the database
10
+ def options
11
+ Dotenv.load
12
+ env_config = ENV.keys.select { |key| key =~ /^SEQUELIZER_/ }.inject({}) do |config, key|
13
+ new_key = key.gsub(/^SEQUELIZER_/, '').downcase
14
+ config[new_key] = ENV[key]
15
+ config
16
+ end
17
+ env_config.empty? ? nil : env_config
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,85 @@
1
+ require_relative 'options'
2
+
3
+ module Sequelizer
4
+ class GemfileModifier
5
+ attr :options
6
+
7
+ def initialize(options = {})
8
+ @options = options
9
+ end
10
+
11
+ def modify
12
+ check_for_gemfile
13
+ if gemfile_needs_modification?
14
+ modify_gemfile
15
+ run_bundle unless options['skip-bundle']
16
+ else
17
+ puts "Gemfile needs no modification"
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def modify_gemfile
24
+ puts %Q|Adding "#{gem_line}" to Gemfile|
25
+ return if options['dry-run']
26
+
27
+ File.write(gemfile, modified_lines.join("\n"))
28
+ end
29
+
30
+ def proper_gem
31
+ opts = Options.new
32
+ @proper_gem ||= case opts.adapter
33
+ when 'postgres'
34
+ 'pg'
35
+ when 'sqlite'
36
+ 'sqlite3'
37
+ when 'mysql'
38
+ 'mysql2'
39
+ when nil
40
+ raise "No database adapter defined in your Sequelizer configuration"
41
+ else
42
+ raise "Don't know which database gem to use with adapter: #{opts.adapter}"
43
+ end
44
+ end
45
+
46
+ def gem_line
47
+ "gem '#{proper_gem}'"
48
+ end
49
+
50
+ def gem_line_comment
51
+ '# ADDED BY SEQUELIZER'
52
+ end
53
+
54
+ def full_gem_line
55
+ [gem_line, gem_line_comment].join(' ')
56
+ end
57
+
58
+ def gemfile_needs_modification?
59
+ !(gemfile_lines.include?(gem_line) || gemfile_lines.include?(full_gem_line))
60
+ end
61
+
62
+ def gemfile_lines
63
+ @gemfile_lines ||= File.readlines(gemfile).map(&:chomp)
64
+ end
65
+
66
+ def modified_lines
67
+ gemfile_lines.select { |l| l !~ Regexp.new(gem_line_comment) } + [full_gem_line]
68
+ end
69
+
70
+ def check_for_gemfile
71
+ return if gemfile.exist?
72
+ raise "Could not find Gemfile in current directory: #{Pathname.pwd}"
73
+ end
74
+
75
+ def run_bundle
76
+ puts "Running `bundle install` to update dependencies"
77
+ system('bundle install')
78
+ end
79
+
80
+ def gemfile
81
+ @gemfile ||= Pathname.new('Gemfile')
82
+ end
83
+ end
84
+ end
85
+
@@ -0,0 +1,64 @@
1
+ require 'sequelizer/yaml_config'
2
+ require 'sequelizer/env_config'
3
+
4
+ module Sequelizer
5
+ class Options
6
+ def initialize(options = nil)
7
+ @options = fix_options(options || db_config)
8
+ end
9
+
10
+ def to_hash
11
+ @options
12
+ end
13
+
14
+ %w(adapter database username password search_path).each do |name|
15
+ define_method(name) do
16
+ @options[name]
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ # If passed a hash, scans hash for certain options and sets up hash
23
+ # to be fed to Sequel.connect
24
+ #
25
+ # If fed anything, like a string that represents the URL for a DB,
26
+ # the string is returned without modification
27
+ def fix_options(sequelizer_options)
28
+ return sequelizer_options unless sequelizer_options.is_a?(Hash)
29
+
30
+ search_path = sequelizer_options['search_path'] || sequelizer_options['schema_search_path']
31
+ sequelizer_options['adapter'] = 'postgres' if sequelizer_options['adapter'] =~ /^postgres/
32
+ if search_path && sequelizer_options['adapter'] =~ /postgres/i
33
+ sequelizer_options['after_connect'] = after_connect(search_path)
34
+ end
35
+
36
+ sequelizer_options
37
+ end
38
+
39
+ # Grabs the database options from
40
+ # - config/database.yml if it exists
41
+ # - environment variables (also reads from .env)
42
+ def db_config
43
+ @db_config ||= begin
44
+ YamlConfig.new.options || EnvConfig.new.options
45
+ end
46
+ end
47
+
48
+ # Returns a proc that should be executed after Sequel connects to the
49
+ # datebase.
50
+ #
51
+ # Right now, the only thing that happens is if we're connecting to
52
+ # PostgreSQL and the schema_search_path is defined, each schema
53
+ # is created if it doesn't exist, then the search_path is set for
54
+ # the connection.
55
+ def after_connect(search_path)
56
+ Proc.new do |conn|
57
+ search_path.split(',').map(&:strip).each do |schema|
58
+ conn.execute("CREATE SCHEMA IF NOT EXISTS #{schema}")
59
+ end
60
+ conn.execute("SET search_path TO #{search_path}")
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,4 @@
1
+ module Sequelizer
2
+ # Version for the gem
3
+ VERSION = "0.0.1"
4
+ end
@@ -0,0 +1,44 @@
1
+ require 'psych'
2
+
3
+ module Sequelizer
4
+ class YamlConfig
5
+ # Returns a set of options pulled from config/database.yml
6
+ # or +nil+ if config/database.yml doesn't exist
7
+ def options
8
+ return nil unless config_file.exist?
9
+ config['adapter'] ? config : config[environment]
10
+ end
11
+
12
+ # The environment to load from database.yml
13
+ #
14
+ # Searches the following environment variables in this order:
15
+ # * SEQUELIZER_ENV
16
+ # * RAILS_ENV
17
+ # * RACK_ENV
18
+ #
19
+ # Lastly, if none of those environment variables are specified, the
20
+ # environment defaults to 'development'
21
+ def environment
22
+ ENV['SEQUELIZER_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
23
+ end
24
+
25
+ private
26
+
27
+ # The Pathname to config/database.yml
28
+ def config_file
29
+ @config_file ||= begin
30
+ root + 'config' + 'database.yml'
31
+ end
32
+ end
33
+
34
+ # The root directory to search for config/database.yml
35
+ def root
36
+ @root ||= Pathname.pwd
37
+ end
38
+
39
+ # The config as read from config/database.yml
40
+ def config
41
+ @config ||= Psych.load_file(config_file)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sequelizer/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'sequelizer'
8
+ spec.version = Sequelizer::VERSION
9
+ spec.authors = ['Ryan Duryea']
10
+ spec.email = ['aguynamedryan@gmail.com']
11
+ spec.summary = %q{Sequel database connections via config/database.yml or .env}
12
+ spec.description = %q{Easily establish a connection to a database via Sequel gem using options specified in config/database.yml or .env files}
13
+ spec.homepage = 'https://github.com/outcomesinsights/sequelizer'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.5'
22
+ spec.add_development_dependency 'guard', '~> 2.0'
23
+ spec.add_development_dependency 'guard-minitest', '~> 2.3'
24
+ spec.add_development_dependency 'minitest', '~> 5.3'
25
+ spec.add_dependency 'sequel', '~> 4.12'
26
+ spec.add_dependency 'dotenv', '~> 0.11'
27
+ spec.add_dependency 'thor', '~> 0.19'
28
+ end
@@ -0,0 +1,48 @@
1
+ require_relative '../test_helper'
2
+ require_relative '../../lib/sequelizer'
3
+
4
+ class TestConnectionMaker < Minitest::Test
5
+ def setup
6
+ @options = { 'adapter' => 'sqlite' }
7
+ @sequel_mock = Minitest::Mock.new
8
+ stub_const(Sequelizer::ConnectionMaker, :Sequel, @sequel_mock)
9
+ @sequel_mock.expect :connect, :connection, [@options]
10
+ end
11
+
12
+ def teardown
13
+ @sequel_mock.verify
14
+ remove_stubbed_const(Sequelizer::ConnectionMaker, :Sequel)
15
+ end
16
+
17
+ def test_accepts_options_as_params
18
+ assert_equal :connection, Sequelizer::ConnectionMaker.new(@options).connection
19
+ end
20
+
21
+ def test_reads_options_from_yaml_config
22
+ yaml_config = Minitest::Mock.new
23
+ yaml_config.expect :options, @options
24
+
25
+ Sequelizer::YamlConfig.stub :new, yaml_config do
26
+ assert_equal :connection, Sequelizer::ConnectionMaker.new.connection
27
+ end
28
+
29
+ yaml_config.verify
30
+ end
31
+
32
+ def test_reads_options_from_env_config_if_no_yaml_config
33
+ yaml_config = Minitest::Mock.new
34
+ yaml_config.expect :options, nil
35
+
36
+ env_config = Minitest::Mock.new
37
+ env_config.expect :options, @options
38
+
39
+ Sequelizer::YamlConfig.stub :new, yaml_config do
40
+ Sequelizer::EnvConfig.stub :new, env_config do
41
+ assert_equal :connection, Sequelizer::ConnectionMaker.new.connection
42
+ end
43
+ end
44
+
45
+ env_config.verify
46
+ yaml_config.verify
47
+ end
48
+ end
@@ -0,0 +1,22 @@
1
+ require_relative '../test_helper'
2
+ require_relative '../../lib/sequelizer/env_config'
3
+
4
+
5
+ class TestEnvConfig < Minitest::Test
6
+ def setup
7
+ @env_config = Sequelizer::EnvConfig.new
8
+ end
9
+ def test_loads_dotenv
10
+ mock = Minitest::Mock.new
11
+ stub_const(Sequelizer::EnvConfig, :Dotenv, mock) do
12
+ mock.expect :load, nil
13
+ @env_config.options
14
+ mock.verify
15
+ end
16
+ end
17
+
18
+ def test_converts_sequelizer_vars_to_options
19
+ ENV['SEQUELIZER_ADAPTER'] = 'sqlite'
20
+ assert_equal({ 'adapter' => 'sqlite' }, @env_config.options)
21
+ end
22
+ end
@@ -0,0 +1,87 @@
1
+ require_relative '../test_helper'
2
+ require_relative '../../lib/sequelizer/gemfile_modifier'
3
+
4
+ class TestGemfileModifier < Minitest::Test
5
+ def setup
6
+ @gm = Sequelizer::GemfileModifier.new
7
+ end
8
+
9
+ def test_dies_if_Gemfile_missing
10
+ pn_mock = Minitest::Mock.new
11
+ pn_mock.expect(:exist?, false)
12
+ Pathname.stub(:new, pn_mock) do
13
+ assert_raises(RuntimeError) { @gm.modify }
14
+ end
15
+ pn_mock.verify
16
+ end
17
+
18
+ def test_quits_if_no_modification_needed
19
+ opts_mock = Minitest::Mock.new
20
+ pn_mock = standard_pn_mock
21
+ opts_mock.expect(:adapter, 'postgres')
22
+ file_mock = Minitest::Mock.new
23
+ file_mock.expect(:readlines, ["gem 'pg'"], [pn_mock])
24
+
25
+ Pathname.stub(:new, pn_mock) do
26
+ Sequelizer::Options.stub(:new, opts_mock) do
27
+ stub_const(Sequelizer::GemfileModifier, :File, file_mock) do
28
+ stub_modifying_methods(@gm) do
29
+ @gm.modify
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ def test_quits_if_no_modification_needed2
37
+ opts_mock = Minitest::Mock.new
38
+ pn_mock = standard_pn_mock
39
+ opts_mock.expect(:adapter, 'postgres')
40
+ file_mock = Minitest::Mock.new
41
+ file_mock.expect(:readlines, ["gem 'pg' # ADDED BY SEQUELIZER"], [pn_mock])
42
+
43
+ Pathname.stub(:new, pn_mock) do
44
+ Sequelizer::Options.stub(:new, opts_mock) do
45
+ stub_const(Sequelizer::GemfileModifier, :File, file_mock) do
46
+ stub_modifying_methods(@gm) do
47
+ @gm.modify
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def test_writes_if_modification_needed
55
+ opts_mock = Minitest::Mock.new
56
+ pn_mock = standard_pn_mock
57
+ opts_mock.expect(:adapter, 'postgres')
58
+ file_mock = Minitest::Mock.new
59
+ file_mock.expect(:readlines, ['#comment line', "gem 'sqlite3' # ADDED BY SEQUELIZER"], [pn_mock])
60
+ file_mock.expect(:write, nil, [pn_mock, ['#comment line', "gem 'pg' # ADDED BY SEQUELIZER"].join("\n")])
61
+
62
+ Pathname.stub(:new, pn_mock) do
63
+ Sequelizer::Options.stub(:new, opts_mock) do
64
+ stub_const(Sequelizer::GemfileModifier, :File, file_mock) do
65
+ stub_modifying_methods(@gm) do
66
+ @gm.modify
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ private
74
+ def standard_pn_mock
75
+ pn_mock = Minitest::Mock.new
76
+ pn_mock.expect(:exist?, true)
77
+ end
78
+
79
+ def stub_modifying_methods(obj)
80
+ obj.stub(:system, nil) do
81
+ obj.stub(:puts, nil) do
82
+ yield
83
+ end
84
+ end
85
+ end
86
+ end
87
+
@@ -0,0 +1,50 @@
1
+ require_relative '../test_helper'
2
+ require_relative '../../lib/sequelizer/yaml_config'
3
+
4
+
5
+ class TestYamlConfig < Minitest::Test
6
+ def setup
7
+ @yaml_config = Sequelizer::YamlConfig.new
8
+ end
9
+
10
+ def test_loads_from_yaml_file_if_present
11
+ mock = Minitest::Mock.new
12
+ file_mock = Minitest::Mock.new
13
+
14
+ stub_const(Sequelizer::YamlConfig, :Psych, mock) do
15
+ mock.expect :load_file, { 'adapter' => 'sqlite' }, [file_mock]
16
+ file_mock.expect :exist?, true
17
+
18
+ @yaml_config.stub :config_file, file_mock do
19
+ assert_equal({ 'adapter' => 'sqlite' }, @yaml_config.options)
20
+ end
21
+
22
+ file_mock.verify
23
+ mock.verify
24
+ end
25
+ end
26
+
27
+ def test_loads_by_environment_if_present
28
+ file_mock = Minitest::Mock.new
29
+ file_mock.expect :exist?, true
30
+ @yaml_config.stub :config_file, file_mock do
31
+ @yaml_config.stub :config, {'development' => { 'adapter' => 'sqlite' }} do
32
+ assert_equal({ 'adapter' => 'sqlite' }, @yaml_config.options)
33
+ end
34
+ end
35
+ file_mock.verify
36
+ end
37
+
38
+ def test_environment_checks_environment_variables
39
+ env_mock = Minitest::Mock.new
40
+ env_mock.expect :[], nil, ['SEQUELIZER_ENV']
41
+ env_mock.expect :[], nil, ['RAILS_ENV']
42
+ env_mock.expect :[], nil, ['RACK_ENV']
43
+
44
+ stub_const(Sequelizer::YamlConfig, :ENV, env_mock) do
45
+ assert_equal 'development', @yaml_config.environment
46
+ end
47
+
48
+ env_mock.verify
49
+ end
50
+ end
@@ -0,0 +1,15 @@
1
+ require 'minitest/autorun'
2
+
3
+ class Minitest::Test
4
+ def stub_const(klass, const, replace, &block)
5
+ klass.send(:const_set, const, replace)
6
+ if block_given?
7
+ yield
8
+ remove_stubbed_const(klass, const)
9
+ end
10
+ end
11
+
12
+ def remove_stubbed_const(klass, const)
13
+ klass.send(:remove_const, const)
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sequelizer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ryan Duryea
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: guard
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: guard-minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sequel
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '4.12'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.12'
83
+ - !ruby/object:Gem::Dependency
84
+ name: dotenv
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.11'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.11'
97
+ - !ruby/object:Gem::Dependency
98
+ name: thor
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.19'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.19'
111
+ description: Easily establish a connection to a database via Sequel gem using options
112
+ specified in config/database.yml or .env files
113
+ email:
114
+ - aguynamedryan@gmail.com
115
+ executables:
116
+ - sequelizer
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - ".gitignore"
121
+ - Gemfile
122
+ - Guardfile
123
+ - LICENSE.txt
124
+ - README.md
125
+ - Rakefile
126
+ - bin/sequelizer
127
+ - examples/database.with_one_set_of_options.yml
128
+ - examples/database.yml
129
+ - examples/dot_env.txt
130
+ - lib/sequelizer.rb
131
+ - lib/sequelizer/cli.rb
132
+ - lib/sequelizer/connection_maker.rb
133
+ - lib/sequelizer/env_config.rb
134
+ - lib/sequelizer/gemfile_modifier.rb
135
+ - lib/sequelizer/options.rb
136
+ - lib/sequelizer/version.rb
137
+ - lib/sequelizer/yaml_config.rb
138
+ - sequelizer.gemspec
139
+ - test/sequelizer/test_connection_maker.rb
140
+ - test/sequelizer/test_env_config.rb
141
+ - test/sequelizer/test_gemfile_modifier.rb
142
+ - test/sequelizer/test_yaml_config.rb
143
+ - test/test_helper.rb
144
+ homepage: https://github.com/outcomesinsights/sequelizer
145
+ licenses:
146
+ - MIT
147
+ metadata: {}
148
+ post_install_message:
149
+ rdoc_options: []
150
+ require_paths:
151
+ - lib
152
+ required_ruby_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ required_rubygems_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ requirements: []
163
+ rubyforge_project:
164
+ rubygems_version: 2.2.2
165
+ signing_key:
166
+ specification_version: 4
167
+ summary: Sequel database connections via config/database.yml or .env
168
+ test_files:
169
+ - test/sequelizer/test_connection_maker.rb
170
+ - test/sequelizer/test_env_config.rb
171
+ - test/sequelizer/test_gemfile_modifier.rb
172
+ - test/sequelizer/test_yaml_config.rb
173
+ - test/test_helper.rb