ardb 0.27.3 → 0.28.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 +4 -4
- data/Gemfile +5 -1
- data/ardb.gemspec +3 -4
- data/lib/ardb.rb +135 -68
- data/lib/ardb/adapter/base.rb +39 -24
- data/lib/ardb/adapter/mysql.rb +1 -2
- data/lib/ardb/adapter/postgresql.rb +14 -12
- data/lib/ardb/adapter/sqlite.rb +3 -8
- data/lib/ardb/adapter_spy.rb +67 -87
- data/lib/ardb/cli.rb +11 -219
- data/lib/ardb/{clirb.rb → cli/clirb.rb} +2 -1
- data/lib/ardb/cli/commands.rb +275 -0
- data/lib/ardb/migration.rb +8 -6
- data/lib/ardb/migration_helpers.rb +1 -1
- data/lib/ardb/pg_json.rb +90 -0
- data/lib/ardb/version.rb +1 -1
- data/test/helper.rb +15 -3
- data/test/support/factory.rb +15 -0
- data/test/support/fake_schema.rb +5 -0
- data/test/support/postgresql/migrations/.gitkeep +0 -0
- data/test/support/postgresql/pg_json_migrations/20160519133432_create_pg_json_migrate_test.rb +13 -0
- data/test/support/postgresql/schema.rb +3 -0
- data/test/support/postgresql/setup_test_db.rb +51 -0
- data/test/support/relative_require_test_db_file.rb +2 -0
- data/test/support/require_test_db_file.rb +1 -0
- data/test/system/pg_json_tests.rb +85 -0
- data/test/unit/adapter/base_tests.rb +104 -39
- data/test/unit/adapter/mysql_tests.rb +2 -1
- data/test/unit/adapter/postgresql_tests.rb +10 -9
- data/test/unit/adapter/sqlite_tests.rb +8 -3
- data/test/unit/adapter_spy_tests.rb +57 -66
- data/test/unit/ardb_tests.rb +323 -36
- data/test/unit/cli_tests.rb +193 -146
- data/test/unit/has_slug_tests.rb +9 -9
- data/test/unit/migration_helpers_tests.rb +18 -12
- data/test/unit/migration_tests.rb +18 -11
- data/test/unit/pg_json_tests.rb +39 -0
- data/test/unit/record_spy_tests.rb +1 -1
- data/test/unit/test_helpers_tests.rb +2 -6
- data/test/unit/use_db_default_tests.rb +2 -2
- metadata +29 -34
- data/lib/ardb/root_path.rb +0 -15
- data/test/unit/config_tests.rb +0 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
|
4
|
-
|
3
|
+
data.tar.gz: 33194d527399daa093277e134bbcda8dee5c6069
|
4
|
+
metadata.gz: 7718eb32a25016d2d620a820b5a2b04244445b6a
|
5
5
|
SHA512:
|
6
|
-
|
7
|
-
|
6
|
+
data.tar.gz: 1597717aba91e83109628879b8ab51c52a81fe47c9f8182bf8bff32e91b7fe30f72a0543d97e1200b77926824b1d669790144fc3bf39bb9e9a30a95110192a69
|
7
|
+
metadata.gz: 02366a02d6aff1a513ea34969017cc07b56be184e906a7cb34b446811c6d4ebaa6fb97f6eddd04344b3f4d2dbca51624c4c57316f996e1b6b98809826e5d03f4
|
data/Gemfile
CHANGED
@@ -2,8 +2,12 @@ source "https://rubygems.org"
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
gem '
|
5
|
+
gem 'pg', "~> 0.17.1"
|
6
|
+
gem 'pry', "~> 0.9.0"
|
6
7
|
|
7
8
|
# Lock down gem versions because they require a newer version of ruby
|
8
9
|
gem 'i18n', "< 0.7"
|
9
10
|
|
11
|
+
platform :ruby_18 do
|
12
|
+
gem 'json', '~> 1.8'
|
13
|
+
end
|
data/ardb.gemspec
CHANGED
@@ -18,12 +18,11 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
|
21
|
-
gem.add_development_dependency("assert", ["~> 2.
|
21
|
+
gem.add_development_dependency("assert", ["~> 2.16.1"])
|
22
22
|
|
23
23
|
gem.add_dependency('activerecord', ["~> 3.2"])
|
24
24
|
gem.add_dependency('activesupport', ["~> 3.2"])
|
25
|
-
gem.add_dependency('much-plugin', ["~> 0.1.
|
26
|
-
gem.add_dependency('
|
27
|
-
gem.add_dependency('scmd', ["~> 3.0.1"])
|
25
|
+
gem.add_dependency('much-plugin', ["~> 0.1.1"])
|
26
|
+
gem.add_dependency('scmd', ["~> 3.0.2"])
|
28
27
|
|
29
28
|
end
|
data/lib/ardb.rb
CHANGED
@@ -1,115 +1,182 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
require 'singleton'
|
3
1
|
require 'active_record'
|
4
|
-
require '
|
2
|
+
require 'logger'
|
5
3
|
|
6
4
|
require 'ardb/version'
|
7
|
-
require 'ardb/root_path'
|
8
5
|
|
9
6
|
ENV['ARDB_DB_FILE'] ||= 'config/db'
|
10
7
|
|
11
8
|
module Ardb
|
12
|
-
NotConfiguredError = Class.new(RuntimeError)
|
13
9
|
|
14
|
-
def self.config
|
15
|
-
|
16
|
-
|
17
|
-
def self.adapter; Adapter.current; end
|
10
|
+
def self.config
|
11
|
+
@config ||= Config.new
|
12
|
+
end
|
18
13
|
|
19
|
-
def self.
|
20
|
-
|
21
|
-
raise NotConfiguredError, "missing required configs"
|
22
|
-
end
|
14
|
+
def self.configure(&block)
|
15
|
+
self.config.tap(&block)
|
23
16
|
end
|
24
17
|
|
18
|
+
def self.adapter; @adapter; end
|
19
|
+
|
25
20
|
def self.init(establish_connection = true)
|
26
21
|
require 'ardb/require_autoloaded_active_record_files'
|
27
|
-
|
28
|
-
|
29
|
-
|
22
|
+
begin
|
23
|
+
require_db_file
|
24
|
+
rescue InvalidDBFileError => exception
|
25
|
+
raise exception.tap{ |e| e.set_backtrace(caller) }
|
26
|
+
end
|
27
|
+
|
28
|
+
self.config.validate!
|
29
|
+
@adapter = Adapter.new(self.config)
|
30
30
|
|
31
31
|
# setup AR
|
32
32
|
ActiveRecord::Base.logger = self.config.logger
|
33
|
-
if establish_connection
|
34
|
-
ActiveRecord::Base.establish_connection(self.config.db_settings)
|
35
|
-
end
|
33
|
+
self.adapter.connect_db if establish_connection
|
36
34
|
end
|
37
35
|
|
38
36
|
def self.escape_like_pattern(pattern, escape_char = nil)
|
39
37
|
self.adapter.escape_like_pattern(pattern, escape_char)
|
40
38
|
end
|
41
39
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
option :username, String, :required => false
|
52
|
-
option :password, String, :required => false
|
53
|
-
option :pool, Integer, :required => false
|
54
|
-
option :checkout_timeout, Integer, :required => false
|
40
|
+
private
|
41
|
+
|
42
|
+
# try requiring the db file via the load path or as an absolute path, if
|
43
|
+
# that fails it tries requiring relative to the current working directory
|
44
|
+
def self.require_db_file
|
45
|
+
begin
|
46
|
+
require ENV['ARDB_DB_FILE']
|
47
|
+
rescue LoadError
|
48
|
+
require File.expand_path(ENV['ARDB_DB_FILE'], ENV['PWD'])
|
55
49
|
end
|
50
|
+
rescue LoadError
|
51
|
+
raise InvalidDBFileError, "can't require `#{ENV['ARDB_DB_FILE']}`, " \
|
52
|
+
"check that the ARDB_DB_FILE env var is set to " \
|
53
|
+
"the file path of your db file"
|
54
|
+
end
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
56
|
+
class Config
|
57
|
+
|
58
|
+
ACTIVERECORD_ATTRS = [
|
59
|
+
:adapter,
|
60
|
+
:database,
|
61
|
+
:encoding,
|
62
|
+
:host,
|
63
|
+
:port,
|
64
|
+
:username,
|
65
|
+
:password,
|
66
|
+
:pool,
|
67
|
+
:checkout_timeout,
|
68
|
+
:min_messages
|
69
|
+
].freeze
|
70
|
+
DEFAULT_MIGRATIONS_PATH = 'db/migrations'.freeze
|
71
|
+
DEFAULT_SCHEMA_PATH = 'db/schema'.freeze
|
72
|
+
RUBY_SCHEMA_FORMAT = :ruby.freeze
|
73
|
+
SQL_SCHEMA_FORMAT = :sql.freeze
|
74
|
+
VALID_SCHEMA_FORMATS = [RUBY_SCHEMA_FORMAT, SQL_SCHEMA_FORMAT].freeze
|
75
|
+
|
76
|
+
attr_accessor *ACTIVERECORD_ATTRS
|
77
|
+
attr_accessor :logger, :root_path
|
78
|
+
attr_reader :schema_format
|
79
|
+
attr_writer :migrations_path, :schema_path
|
80
|
+
|
81
|
+
def initialize
|
82
|
+
@logger = Logger.new(STDOUT)
|
83
|
+
@root_path = ENV['PWD']
|
84
|
+
@migrations_path = DEFAULT_MIGRATIONS_PATH
|
85
|
+
@schema_path = DEFAULT_SCHEMA_PATH
|
86
|
+
@schema_format = RUBY_SCHEMA_FORMAT
|
69
87
|
end
|
70
88
|
|
71
|
-
|
89
|
+
def migrations_path
|
90
|
+
File.expand_path(@migrations_path.to_s, @root_path.to_s)
|
91
|
+
end
|
72
92
|
|
73
|
-
|
74
|
-
|
93
|
+
def schema_path
|
94
|
+
File.expand_path(@schema_path.to_s, @root_path.to_s)
|
95
|
+
end
|
75
96
|
|
76
|
-
|
97
|
+
def schema_format=(new_value)
|
98
|
+
@schema_format = begin
|
99
|
+
new_value.to_sym
|
100
|
+
rescue NoMethodError
|
101
|
+
raise ArgumentError, "schema format must be a `Symbol`", caller
|
102
|
+
end
|
103
|
+
end
|
77
104
|
|
78
|
-
def
|
79
|
-
|
105
|
+
def activerecord_connect_hash
|
106
|
+
ACTIVERECORD_ATTRS.inject({}) do |h, attr_name|
|
107
|
+
value = self.send(attr_name)
|
108
|
+
!value.nil? ? h.merge!(attr_name.to_s => value) : h
|
109
|
+
end
|
80
110
|
end
|
81
111
|
|
82
|
-
def
|
83
|
-
|
112
|
+
def validate!
|
113
|
+
if self.adapter.to_s.empty? || self.database.to_s.empty?
|
114
|
+
raise ConfigurationError, "an adapter and database must be provided"
|
115
|
+
elsif !VALID_SCHEMA_FORMATS.include?(self.schema_format)
|
116
|
+
raise ConfigurationError, "schema format must be one of: " \
|
117
|
+
"#{VALID_SCHEMA_FORMATS.join(', ')}"
|
118
|
+
end
|
119
|
+
true
|
84
120
|
end
|
85
121
|
|
86
|
-
def
|
87
|
-
|
88
|
-
|
122
|
+
def ==(other)
|
123
|
+
if other.kind_of?(self.class)
|
124
|
+
self.activerecord_connect_hash == other.activerecord_connect_hash &&
|
125
|
+
self.logger == other.logger &&
|
126
|
+
self.root_path == other.root_path &&
|
127
|
+
self.schema_format == other.schema_format &&
|
128
|
+
self.migrations_path == other.migrations_path &&
|
129
|
+
self.schema_path == other.schema_path
|
130
|
+
else
|
131
|
+
super
|
132
|
+
end
|
89
133
|
end
|
90
|
-
alias_method :sqlite3, :sqlite
|
91
134
|
|
92
|
-
|
93
|
-
|
94
|
-
|
135
|
+
end
|
136
|
+
|
137
|
+
module Adapter
|
138
|
+
|
139
|
+
VALID_ADAPTERS = [
|
140
|
+
'sqlite',
|
141
|
+
'sqlite3',
|
142
|
+
'postgresql',
|
143
|
+
'postgres',
|
144
|
+
'mysql',
|
145
|
+
'mysql2'
|
146
|
+
].freeze
|
147
|
+
|
148
|
+
def self.new(config)
|
149
|
+
if !VALID_ADAPTERS.include?(config.adapter)
|
150
|
+
raise InvalidAdapterError, "invalid adapter: `#{config.adapter}`"
|
151
|
+
end
|
152
|
+
self.send(config.adapter, config)
|
95
153
|
end
|
96
154
|
|
97
|
-
def
|
98
|
-
require 'ardb/adapter/
|
99
|
-
Adapter::
|
155
|
+
def self.sqlite(config)
|
156
|
+
require 'ardb/adapter/sqlite'
|
157
|
+
Adapter::Sqlite.new(config)
|
100
158
|
end
|
101
|
-
alias_method :mysql2, :mysql
|
102
159
|
|
103
|
-
|
160
|
+
def self.sqlite3(config); self.sqlite(config); end
|
104
161
|
|
105
|
-
def self.
|
106
|
-
|
162
|
+
def self.postgresql(config)
|
163
|
+
require 'ardb/adapter/postgresql'
|
164
|
+
Adapter::Postgresql.new(config)
|
107
165
|
end
|
108
166
|
|
109
|
-
def self.
|
110
|
-
|
167
|
+
def self.postgres(config); self.postgresql(config); end
|
168
|
+
|
169
|
+
def self.mysql(config)
|
170
|
+
require 'ardb/adapter/mysql'
|
171
|
+
Adapter::Mysql.new(config)
|
111
172
|
end
|
112
173
|
|
174
|
+
def self.mysql2(config); self.mysql(config); end
|
175
|
+
|
113
176
|
end
|
114
177
|
|
178
|
+
InvalidDBFileError = Class.new(ArgumentError)
|
179
|
+
ConfigurationError = Class.new(ArgumentError)
|
180
|
+
InvalidAdapterError = Class.new(RuntimeError)
|
181
|
+
|
115
182
|
end
|
data/lib/ardb/adapter/base.rb
CHANGED
@@ -1,18 +1,27 @@
|
|
1
|
+
require 'ardb'
|
2
|
+
|
1
3
|
module Ardb; end
|
2
|
-
|
4
|
+
module Ardb::Adapter
|
3
5
|
|
4
6
|
class Base
|
5
7
|
|
6
|
-
attr_reader :
|
7
|
-
|
8
|
+
attr_reader :config
|
9
|
+
|
10
|
+
def initialize(config)
|
11
|
+
@config = config
|
12
|
+
end
|
13
|
+
|
14
|
+
def connect_hash; self.config.activerecord_connect_hash; end
|
15
|
+
def database; self.config.database; end
|
16
|
+
def migrations_path; self.config.migrations_path; end
|
17
|
+
def schema_format; self.config.schema_format; end
|
18
|
+
|
19
|
+
def ruby_schema_path
|
20
|
+
@ruby_schema_path ||= "#{self.config.schema_path}.rb"
|
21
|
+
end
|
8
22
|
|
9
|
-
def
|
10
|
-
@
|
11
|
-
@database = Ardb.config.db.database
|
12
|
-
@schema_format = Ardb.config.schema_format
|
13
|
-
schema_path = Ardb.config.schema_path
|
14
|
-
@ruby_schema_path = "#{schema_path}.rb"
|
15
|
-
@sql_schema_path = "#{schema_path}.sql"
|
23
|
+
def sql_schema_path
|
24
|
+
@sql_schema_path ||= "#{self.config.schema_path}.sql"
|
16
25
|
end
|
17
26
|
|
18
27
|
def escape_like_pattern(pattern, escape_char = nil)
|
@@ -29,14 +38,18 @@ class Ardb::Adapter
|
|
29
38
|
def create_db(*args); raise NotImplementedError; end
|
30
39
|
def drop_db(*args); raise NotImplementedError; end
|
31
40
|
|
41
|
+
def drop_tables(*args); raise NotImplementedError; end
|
42
|
+
|
32
43
|
def connect_db
|
33
|
-
ActiveRecord::Base.
|
44
|
+
ActiveRecord::Base.establish_connection(self.connect_hash)
|
45
|
+
# checkout a connection to ensure we can connect to the DB, we don't do
|
46
|
+
# anything with the connection and immediately check it back in
|
47
|
+
ActiveRecord::Base.connection_pool.with_connection{ }
|
34
48
|
end
|
35
49
|
|
36
50
|
def migrate_db
|
37
51
|
verbose = ENV["MIGRATE_QUIET"].nil?
|
38
52
|
version = ENV["MIGRATE_VERSION"] ? ENV["MIGRATE_VERSION"].to_i : nil
|
39
|
-
migrations_path = Ardb.config.migrations_path
|
40
53
|
|
41
54
|
if defined?(ActiveRecord::Migration::CommandRecorder)
|
42
55
|
require 'ardb/migration_helpers'
|
@@ -45,26 +58,24 @@ class Ardb::Adapter
|
|
45
58
|
end
|
46
59
|
end
|
47
60
|
|
48
|
-
ActiveRecord::Migrator.migrations_path = migrations_path
|
61
|
+
ActiveRecord::Migrator.migrations_path = self.migrations_path
|
49
62
|
ActiveRecord::Migration.verbose = verbose
|
50
|
-
ActiveRecord::Migrator.migrate(migrations_path, version) do |migration|
|
63
|
+
ActiveRecord::Migrator.migrate(self.migrations_path, version) do |migration|
|
51
64
|
ENV["MIGRATE_SCOPE"].blank? || (ENV["MIGRATE_SCOPE"] == migration.scope)
|
52
65
|
end
|
53
66
|
end
|
54
67
|
|
55
|
-
def drop_tables(*args); raise NotImplementedError; end
|
56
|
-
|
57
68
|
def load_schema
|
58
69
|
# silence STDOUT
|
59
70
|
current_stdout = $stdout.dup
|
60
71
|
$stdout = File.new('/dev/null', 'w')
|
61
|
-
load_ruby_schema if
|
62
|
-
load_sql_schema if
|
72
|
+
load_ruby_schema if self.schema_format == Ardb::Config::RUBY_SCHEMA_FORMAT
|
73
|
+
load_sql_schema if self.schema_format == Ardb::Config::SQL_SCHEMA_FORMAT
|
63
74
|
$stdout = current_stdout
|
64
75
|
end
|
65
76
|
|
66
77
|
def load_ruby_schema
|
67
|
-
load
|
78
|
+
load self.ruby_schema_path
|
68
79
|
end
|
69
80
|
|
70
81
|
def load_sql_schema
|
@@ -76,14 +87,14 @@ class Ardb::Adapter
|
|
76
87
|
current_stdout = $stdout.dup
|
77
88
|
$stdout = File.new('/dev/null', 'w')
|
78
89
|
dump_ruby_schema
|
79
|
-
dump_sql_schema if
|
90
|
+
dump_sql_schema if self.schema_format == Ardb::Config::SQL_SCHEMA_FORMAT
|
80
91
|
$stdout = current_stdout
|
81
92
|
end
|
82
93
|
|
83
94
|
def dump_ruby_schema
|
84
95
|
require 'active_record/schema_dumper'
|
85
|
-
FileUtils.mkdir_p File.dirname(
|
86
|
-
File.open(
|
96
|
+
FileUtils.mkdir_p File.dirname(self.ruby_schema_path)
|
97
|
+
File.open(self.ruby_schema_path, 'w:utf-8') do |file|
|
87
98
|
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
88
99
|
end
|
89
100
|
end
|
@@ -92,8 +103,12 @@ class Ardb::Adapter
|
|
92
103
|
raise NotImplementedError
|
93
104
|
end
|
94
105
|
|
95
|
-
def ==(
|
96
|
-
self.class
|
106
|
+
def ==(other)
|
107
|
+
if other.kind_of?(self.class)
|
108
|
+
self.config == other.config
|
109
|
+
else
|
110
|
+
super
|
111
|
+
end
|
97
112
|
end
|
98
113
|
|
99
114
|
end
|
data/lib/ardb/adapter/mysql.rb
CHANGED
@@ -1,26 +1,28 @@
|
|
1
|
-
require 'ardb'
|
2
1
|
require 'ardb/adapter/base'
|
3
2
|
|
4
|
-
|
3
|
+
module Ardb::Adapter
|
5
4
|
|
6
5
|
class Postgresql < Base
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
# the 'postgres' db is a "public" (doesn't typically require auth/grants to
|
8
|
+
# connect to) db that typically exists for all postgres installations; the
|
9
|
+
# adapter uses it to create/drop other databases
|
10
|
+
def public_connect_hash
|
11
|
+
@public_connect_hash ||= self.connect_hash.merge({
|
10
12
|
'database' => 'postgres',
|
11
13
|
'schema_search_path' => 'public'
|
12
14
|
})
|
13
15
|
end
|
14
16
|
|
15
17
|
def create_db
|
16
|
-
ActiveRecord::Base.establish_connection(self.
|
17
|
-
ActiveRecord::Base.connection.create_database(self.database, self.
|
18
|
-
ActiveRecord::Base.establish_connection(self.
|
18
|
+
ActiveRecord::Base.establish_connection(self.public_connect_hash)
|
19
|
+
ActiveRecord::Base.connection.create_database(self.database, self.connect_hash)
|
20
|
+
ActiveRecord::Base.establish_connection(self.connect_hash)
|
19
21
|
end
|
20
22
|
|
21
23
|
def drop_db
|
22
24
|
begin
|
23
|
-
ActiveRecord::Base.establish_connection(self.
|
25
|
+
ActiveRecord::Base.establish_connection(self.public_connect_hash)
|
24
26
|
ActiveRecord::Base.connection.tap do |conn|
|
25
27
|
conn.execute "UPDATE pg_catalog.pg_database"\
|
26
28
|
" SET datallowconn=false WHERE datname='#{self.database}'"
|
@@ -74,10 +76,10 @@ class Ardb::Adapter
|
|
74
76
|
|
75
77
|
def env_var_hash
|
76
78
|
@env_var_hash ||= {
|
77
|
-
'PGHOST' => self.
|
78
|
-
'PGPORT' => self.
|
79
|
-
'PGUSER' => self.
|
80
|
-
'PGPASSWORD' => self.
|
79
|
+
'PGHOST' => self.connect_hash['host'],
|
80
|
+
'PGPORT' => self.connect_hash['port'],
|
81
|
+
'PGUSER' => self.connect_hash['username'],
|
82
|
+
'PGPASSWORD' => self.connect_hash['password']
|
81
83
|
}
|
82
84
|
end
|
83
85
|
|