ardb 0.28.3 → 0.30.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.
Files changed (60) hide show
  1. checksums.yaml +7 -7
  2. data/.l.yml +9 -0
  3. data/.rubocop.yml +3 -0
  4. data/.ruby-version +1 -0
  5. data/.t.yml +6 -0
  6. data/Gemfile +24 -8
  7. data/README.md +252 -3
  8. data/ardb.gemspec +14 -10
  9. data/bin/ardb +3 -1
  10. data/lib/ardb/adapter/base.rb +72 -47
  11. data/lib/ardb/adapter/mysql.rb +4 -17
  12. data/lib/ardb/adapter/postgresql.rb +51 -46
  13. data/lib/ardb/adapter/sqlite.rb +11 -15
  14. data/lib/ardb/adapter_spy.rb +18 -30
  15. data/lib/ardb/cli/clirb.rb +16 -18
  16. data/lib/ardb/cli/commands.rb +308 -129
  17. data/lib/ardb/cli.rb +29 -24
  18. data/lib/ardb/db_tests.rb +4 -4
  19. data/lib/ardb/default_order_by.rb +13 -21
  20. data/lib/ardb/migration.rb +15 -16
  21. data/lib/ardb/record_spy.rb +46 -61
  22. data/lib/ardb/relation_spy.rb +28 -32
  23. data/lib/ardb/require_autoloaded_active_record_files.rb +258 -57
  24. data/lib/ardb/test_helpers.rb +33 -29
  25. data/lib/ardb/use_db_default.rb +13 -21
  26. data/lib/ardb/version.rb +3 -1
  27. data/lib/ardb.rb +105 -86
  28. data/script/determine_autoloaded_active_record_files.rb +31 -24
  29. data/test/helper.rb +6 -13
  30. data/test/support/factory.rb +4 -3
  31. data/test/support/fake_schema.rb +3 -1
  32. data/test/support/postgresql/migrations/{.gitkeep → .keep} +0 -0
  33. data/test/support/postgresql/schema.rb +2 -1
  34. data/test/support/postgresql/setup_test_db.rb +23 -21
  35. data/test/support/relative_require_test_db_file.rb +1 -0
  36. data/test/support/require_test_db_file.rb +1 -0
  37. data/test/system/.keep +0 -0
  38. data/test/unit/adapter/base_tests.rb +80 -55
  39. data/test/unit/adapter/mysql_tests.rb +4 -19
  40. data/test/unit/adapter/postgresql_tests.rb +21 -30
  41. data/test/unit/adapter/sqlite_tests.rb +5 -11
  42. data/test/unit/adapter_spy_tests.rb +6 -17
  43. data/test/unit/ardb_tests.rb +75 -53
  44. data/test/unit/cli_tests.rb +234 -158
  45. data/test/unit/db_tests_tests.rb +7 -7
  46. data/test/unit/default_order_by_tests.rb +26 -24
  47. data/test/unit/migration_tests.rb +17 -18
  48. data/test/unit/record_spy_tests.rb +45 -41
  49. data/test/unit/relation_spy_tests.rb +40 -63
  50. data/test/unit/test_helpers_tests.rb +7 -15
  51. data/test/unit/use_db_default_tests.rb +35 -27
  52. metadata +109 -87
  53. data/lib/ardb/has_slug.rb +0 -107
  54. data/lib/ardb/migration_helpers.rb +0 -77
  55. data/lib/ardb/pg_json.rb +0 -90
  56. data/test/support/postgresql/pg_json_migrations/20160519133432_create_pg_json_migrate_test.rb +0 -13
  57. data/test/system/pg_json_tests.rb +0 -85
  58. data/test/unit/has_slug_tests.rb +0 -341
  59. data/test/unit/migration_helpers_tests.rb +0 -65
  60. data/test/unit/pg_json_tests.rb +0 -39
data/lib/ardb.rb CHANGED
@@ -1,97 +1,109 @@
1
- require 'active_record'
2
- require 'logger'
1
+ # frozen_string_literal: true
3
2
 
4
- require 'ardb/version'
3
+ require "active_record"
4
+ require "logger"
5
5
 
6
- ENV['ARDB_DB_FILE'] ||= 'config/db'
6
+ require "ardb/version"
7
7
 
8
- module Ardb
8
+ ENV["ARDB_DB_FILE"] ||= "config/db"
9
9
 
10
+ module Ardb
10
11
  def self.config
11
12
  @config ||= Config.new
12
13
  end
13
14
 
14
15
  def self.configure(&block)
15
- self.config.tap(&block)
16
+ config.tap(&block)
16
17
  end
17
18
 
18
19
  def self.adapter
19
20
  @adapter || raise(NotInitializedError.new(caller))
20
21
  end
21
22
 
22
- def self.reset_adapter; @adapter = nil; end
23
+ def self.reset_adapter
24
+ @adapter = nil
25
+ end
23
26
 
24
27
  def self.init(establish_connection = true)
25
- require 'ardb/require_autoloaded_active_record_files'
28
+ require "ardb/require_autoloaded_active_record_files"
26
29
  begin
27
30
  require_db_file
28
- rescue InvalidDBFileError => exception
29
- exception.set_backtrace(caller)
30
- raise exception
31
+ rescue InvalidDBFileError => ex
32
+ ex.set_backtrace(caller)
33
+ raise ex
31
34
  end
32
35
 
33
- self.config.validate!
34
- @adapter = Adapter.new(self.config)
36
+ config.validate!
37
+ @adapter = Adapter.new(config)
35
38
 
36
39
  # setup AR
37
- ActiveRecord::Base.logger = self.config.logger
38
- self.adapter.connect_db if establish_connection
40
+ if ActiveRecord.respond_to?(:default_timezone=)
41
+ ActiveRecord.default_timezone = config.default_timezone
42
+ else
43
+ ActiveRecord::Base.default_timezone = config.default_timezone
44
+ end
45
+ ActiveRecord::Base.logger = config.logger
46
+ adapter.connect_db if establish_connection
39
47
  end
40
48
 
41
49
  def self.escape_like_pattern(pattern, escape_char = nil)
42
- self.adapter.escape_like_pattern(pattern, escape_char)
43
- rescue NotInitializedError => exception
44
- exception.set_backtrace(caller)
45
- raise exception
50
+ adapter.escape_like_pattern(pattern, escape_char)
51
+ rescue NotInitializedError => ex
52
+ ex.set_backtrace(caller)
53
+ raise ex
46
54
  end
47
55
 
48
- private
49
-
50
56
  # try requiring the db file via the load path or as an absolute path, if
51
57
  # that fails it tries requiring relative to the current working directory
52
58
  def self.require_db_file
53
59
  begin
54
- require ENV['ARDB_DB_FILE']
60
+ begin
61
+ require ENV["ARDB_DB_FILE"]
62
+ rescue LoadError
63
+ require File.expand_path(ENV["ARDB_DB_FILE"], ENV["PWD"])
64
+ end
55
65
  rescue LoadError
56
- require File.expand_path(ENV['ARDB_DB_FILE'], ENV['PWD'])
66
+ raise(
67
+ InvalidDBFileError,
68
+ "can't require `#{ENV["ARDB_DB_FILE"]}`, check that the ARDB_DB_FILE "\
69
+ "env var is set to the file path of your db file",
70
+ )
57
71
  end
58
- rescue LoadError
59
- raise InvalidDBFileError, "can't require `#{ENV['ARDB_DB_FILE']}`, " \
60
- "check that the ARDB_DB_FILE env var is set to " \
61
- "the file path of your db file"
62
72
  end
63
73
 
64
74
  class Config
65
-
66
- ACTIVERECORD_ATTRS = [
67
- :adapter,
68
- :database,
69
- :encoding,
70
- :host,
71
- :port,
72
- :username,
73
- :password,
74
- :pool,
75
- :checkout_timeout,
76
- :min_messages
77
- ].freeze
78
- DEFAULT_MIGRATIONS_PATH = 'db/migrations'.freeze
79
- DEFAULT_SCHEMA_PATH = 'db/schema'.freeze
80
- RUBY_SCHEMA_FORMAT = :ruby.freeze
81
- SQL_SCHEMA_FORMAT = :sql.freeze
75
+ ACTIVERECORD_ATTRS =
76
+ [
77
+ :adapter,
78
+ :database,
79
+ :encoding,
80
+ :host,
81
+ :port,
82
+ :username,
83
+ :password,
84
+ :pool,
85
+ :checkout_timeout,
86
+ :min_messages,
87
+ ].freeze
88
+
89
+ DEFAULT_MIGRATIONS_PATH = "db/migrations"
90
+ DEFAULT_SCHEMA_PATH = "db/schema"
91
+ RUBY_SCHEMA_FORMAT = :ruby
92
+ SQL_SCHEMA_FORMAT = :sql
82
93
  VALID_SCHEMA_FORMATS = [RUBY_SCHEMA_FORMAT, SQL_SCHEMA_FORMAT].freeze
83
94
 
84
- attr_accessor *ACTIVERECORD_ATTRS
85
- attr_accessor :logger, :root_path
95
+ attr_accessor(*ACTIVERECORD_ATTRS)
96
+ attr_accessor :default_timezone, :logger, :root_path
86
97
  attr_reader :schema_format
87
98
  attr_writer :migrations_path, :schema_path
88
99
 
89
100
  def initialize
90
- @logger = Logger.new(STDOUT)
91
- @root_path = ENV['PWD']
92
- @migrations_path = DEFAULT_MIGRATIONS_PATH
93
- @schema_path = DEFAULT_SCHEMA_PATH
94
- @schema_format = RUBY_SCHEMA_FORMAT
101
+ @default_timezone = :utc
102
+ @logger = Logger.new(STDOUT)
103
+ @root_path = ENV["PWD"]
104
+ @migrations_path = DEFAULT_MIGRATIONS_PATH
105
+ @schema_path = DEFAULT_SCHEMA_PATH
106
+ @schema_format = RUBY_SCHEMA_FORMAT
95
107
  end
96
108
 
97
109
  def migrations_path
@@ -103,84 +115,92 @@ module Ardb
103
115
  end
104
116
 
105
117
  def schema_format=(new_value)
106
- @schema_format = begin
107
- new_value.to_sym
108
- rescue NoMethodError
109
- raise ArgumentError, "schema format must be a `Symbol`", caller
110
- end
118
+ @schema_format =
119
+ begin
120
+ new_value.to_sym
121
+ rescue NoMethodError
122
+ raise ArgumentError, "schema format must be a `Symbol`", caller
123
+ end
111
124
  end
112
125
 
113
126
  def activerecord_connect_hash
114
- ACTIVERECORD_ATTRS.inject({}) do |h, attr_name|
115
- value = self.send(attr_name)
127
+ ACTIVERECORD_ATTRS.reduce({}) do |h, attr_name|
128
+ value = send(attr_name)
116
129
  !value.nil? ? h.merge!(attr_name.to_s => value) : h
117
130
  end
118
131
  end
119
132
 
120
133
  def validate!
121
- if self.adapter.to_s.empty? || self.database.to_s.empty?
134
+ if adapter.to_s.empty? || database.to_s.empty?
122
135
  raise ConfigurationError, "an adapter and database must be provided"
123
- elsif !VALID_SCHEMA_FORMATS.include?(self.schema_format)
136
+ end
137
+
138
+ unless VALID_SCHEMA_FORMATS.include?(schema_format)
124
139
  raise ConfigurationError, "schema format must be one of: " \
125
- "#{VALID_SCHEMA_FORMATS.join(', ')}"
140
+ "#{VALID_SCHEMA_FORMATS.join(", ")}"
126
141
  end
142
+
127
143
  true
128
144
  end
129
145
 
130
146
  def ==(other)
131
- if other.kind_of?(self.class)
132
- self.activerecord_connect_hash == other.activerecord_connect_hash &&
133
- self.logger == other.logger &&
134
- self.root_path == other.root_path &&
135
- self.schema_format == other.schema_format &&
136
- self.migrations_path == other.migrations_path &&
137
- self.schema_path == other.schema_path
147
+ if other.is_a?(self.class)
148
+ activerecord_connect_hash == other.activerecord_connect_hash &&
149
+ default_timezone == other.default_timezone &&
150
+ logger == other.logger &&
151
+ root_path == other.root_path &&
152
+ schema_format == other.schema_format &&
153
+ migrations_path == other.migrations_path &&
154
+ schema_path == other.schema_path
138
155
  else
139
156
  super
140
157
  end
141
158
  end
142
-
143
159
  end
144
160
 
145
161
  module Adapter
146
-
147
162
  VALID_ADAPTERS = [
148
- 'sqlite',
149
- 'sqlite3',
150
- 'postgresql',
151
- 'postgres',
152
- 'mysql',
153
- 'mysql2'
163
+ "sqlite",
164
+ "sqlite3",
165
+ "postgresql",
166
+ "postgres",
167
+ "mysql",
168
+ "mysql2",
154
169
  ].freeze
155
170
 
156
171
  def self.new(config)
157
- if !VALID_ADAPTERS.include?(config.adapter)
172
+ unless VALID_ADAPTERS.include?(config.adapter)
158
173
  raise InvalidAdapterError, "invalid adapter: `#{config.adapter}`"
159
174
  end
160
- self.send(config.adapter, config)
175
+ send(config.adapter, config)
161
176
  end
162
177
 
163
178
  def self.sqlite(config)
164
- require 'ardb/adapter/sqlite'
179
+ require "ardb/adapter/sqlite"
165
180
  Adapter::Sqlite.new(config)
166
181
  end
167
182
 
168
- def self.sqlite3(config); self.sqlite(config); end
183
+ def self.sqlite3(config)
184
+ sqlite(config)
185
+ end
169
186
 
170
187
  def self.postgresql(config)
171
- require 'ardb/adapter/postgresql'
188
+ require "ardb/adapter/postgresql"
172
189
  Adapter::Postgresql.new(config)
173
190
  end
174
191
 
175
- def self.postgres(config); self.postgresql(config); end
192
+ def self.postgres(config)
193
+ postgresql(config)
194
+ end
176
195
 
177
196
  def self.mysql(config)
178
- require 'ardb/adapter/mysql'
197
+ require "ardb/adapter/mysql"
179
198
  Adapter::Mysql.new(config)
180
199
  end
181
200
 
182
- def self.mysql2(config); self.mysql(config); end
183
-
201
+ def self.mysql2(config)
202
+ mysql(config)
203
+ end
184
204
  end
185
205
 
186
206
  InvalidDBFileError = Class.new(ArgumentError)
@@ -193,5 +213,4 @@ module Ardb
193
213
  set_backtrace(backtrace)
194
214
  end
195
215
  end
196
-
197
216
  end
@@ -1,8 +1,10 @@
1
- require 'active_record'
1
+ # frozen_string_literal: true
2
2
 
3
- # this can be slow, this is one of the reasons this shouldn't be done during
3
+ require "active_record"
4
+
5
+ # this can be slow, this is one of the reasons this shouldn"t be done during
4
6
  # the startup of our apps
5
- gemspec = Gem.loaded_specs['activerecord']
7
+ gemspec = Gem.loaded_specs["activerecord"]
6
8
 
7
9
  puts "Looking at files in: "
8
10
  puts " #{gemspec.lib_dirs_glob.inspect}"
@@ -11,16 +13,21 @@ paths = Dir["#{gemspec.lib_dirs_glob}/**/*.rb"]
11
13
 
12
14
  # these are regexs for files we want to ignore requiring. for example,
13
15
  # generators fail when we try to require them. the others are pieces of active
14
- # record we don't use in a production environment
16
+ # record we don"t use in a production environment
15
17
  ignored_regexes = [
16
- /rails\/generators/,
17
- /active_record\/railtie/,
18
- /active_record\/migration/,
19
- /active_record\/fixtures/,
20
- /active_record\/schema/,
21
- /active_record\/connection_adapters/,
22
- /active_record\/test_case/,
23
- /active_record\/coders\/yaml_column/
18
+ %r{rails/generators},
19
+ %r{active_record/railtie},
20
+ %r{active_record/migration},
21
+ %r{active_record/fixtures},
22
+ %r{active_record/fixture_set},
23
+ %r{active_record/schema},
24
+ %r{active_record/connection_adapters},
25
+ %r{active_record/test_case},
26
+ %r{active_record/test_databases},
27
+ %r{active_record/test_fixtures},
28
+ %r{active_record/coders/yaml_column},
29
+ # `destroy_association_async_job` requires `ActiveJob` to be required.
30
+ %r{active_record/destroy_association_async_job},
24
31
  ]
25
32
 
26
33
  Result = Struct.new(:file, :state, :reason)
@@ -31,18 +38,18 @@ ignored = []
31
38
  errored = []
32
39
 
33
40
  paths.sort.each do |full_path|
34
- relative_path_with_rb = full_path.gsub("#{gemspec.lib_dirs_glob}/", '')
35
- relative_path = relative_path_with_rb.gsub(/\.rb\z/, '')
41
+ relative_path_with_rb = full_path.gsub("#{gemspec.lib_dirs_glob}/", "")
42
+ relative_path = relative_path_with_rb.gsub(/\.rb\z/, "")
36
43
 
37
44
  result = Result.new(relative_path)
38
45
 
39
- # see if it's ignored
46
+ # see if it"s ignored
40
47
  ignored_regexes.each do |regex|
41
- if relative_path =~ regex
42
- result.state = :ignored
43
- result.reason = "matched #{regex}"
44
- break
45
- end
48
+ next unless relative_path =~ regex
49
+
50
+ result.state = :ignored
51
+ result.reason = "matched #{regex}"
52
+ break
46
53
  end
47
54
  if result.state == :ignored
48
55
  ignored << result
@@ -51,14 +58,14 @@ paths.sort.each do |full_path|
51
58
 
52
59
  # try requiring the file
53
60
  begin
54
- if result.state = require(relative_path)
61
+ if (result.state = require(relative_path))
55
62
  needs_to_be_required << result
56
63
  else
57
64
  already_required << result
58
65
  end
59
- rescue LoadError, SyntaxError => exception
66
+ rescue LoadError, SyntaxError => ex
60
67
  result.state = :errored
61
- result.reason = "#{exception.class}: #{exception.message}"
68
+ result.reason = "#{ex.class}: #{ex.message}"
62
69
  errored << result
63
70
  end
64
71
  end
@@ -87,5 +94,5 @@ puts "\n"
87
94
 
88
95
  puts "Needs To Be Required:\n"
89
96
  needs_to_be_required.each do |result|
90
- puts "require '#{result.file}'"
97
+ puts "require \"#{result.file}\""
91
98
  end
data/test/helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # this file is automatically required when you run `assert`
2
4
  # put any test helpers here
3
5
 
@@ -7,19 +9,10 @@ $LOAD_PATH.unshift(File.expand_path("../..", __FILE__))
7
9
  TEST_SUPPORT_PATH = File.expand_path("../support", __FILE__)
8
10
  TMP_PATH = File.expand_path("../../tmp", __FILE__)
9
11
 
10
- require 'logger'
12
+ require "logger"
11
13
  log_path = File.expand_path("../../log/test.log", __FILE__)
12
- TEST_LOGGER = Logger.new(File.open(log_path, 'w'))
14
+ TEST_LOGGER = Logger.new(File.open(log_path, "w"))
13
15
 
14
16
  # require pry for debugging (`binding.pry`)
15
- require 'pry'
16
- require 'test/support/factory'
17
-
18
- # 1.8.7 backfills
19
-
20
- # Array#sample
21
- if !(a = Array.new).respond_to?(:sample) && a.respond_to?(:choice)
22
- class Array
23
- alias_method :sample, :choice
24
- end
25
- end
17
+ require "pry"
18
+ require "test/support/factory"
@@ -1,10 +1,12 @@
1
- require 'assert/factory'
1
+ # frozen_string_literal: true
2
+
3
+ require "assert/factory"
2
4
 
3
5
  module Factory
4
6
  extend Assert::Factory
5
7
 
6
8
  def self.migration_id
7
- # identifiers need to be plural b/c af activesupport's pluralize
9
+ # identifiers need to be plural b/c af activesupport"s pluralize
8
10
  "#{Factory.string}_things"
9
11
  end
10
12
 
@@ -22,5 +24,4 @@ module Factory
22
24
  c.min_messages = Factory.string
23
25
  end
24
26
  end
25
-
26
27
  end
@@ -1,4 +1,6 @@
1
- if !defined?(FAKE_SCHEMA)
1
+ # frozen_string_literal: true
2
+
3
+ unless defined?(FAKE_SCHEMA)
2
4
  fake_schema_class = Struct.new(:load_count)
3
5
  FAKE_SCHEMA = fake_schema_class.new(0)
4
6
  end
@@ -1,3 +1,4 @@
1
- ActiveRecord::Schema.define(:version => 0) do
1
+ # frozen_string_literal: true
2
2
 
3
+ ActiveRecord::Schema.define(version: 0) do
3
4
  end
@@ -1,26 +1,29 @@
1
- require 'assert'
2
- require 'ardb'
1
+ # frozen_string_literal: true
2
+
3
+ require "assert"
4
+ require "ardb"
3
5
 
4
6
  class PostgresqlDbTests < Assert::Context
5
7
  setup do
6
- @orig_env_ardb_db_file = ENV['ARDB_DB_FILE']
8
+ @orig_env_ardb_db_file = ENV["ARDB_DB_FILE"]
7
9
  ActiveRecord::Base.logger = @orig_ar_loggerF
8
10
 
9
- # no-op, we're manually configuring ardb so we don't need this to do anything
10
- ENV['ARDB_DB_FILE'] = File.join(TEST_SUPPORT_PATH, 'require_test_db_file')
11
-
12
- @ardb_config = Ardb::Config.new.tap do |c|
13
- c.adapter = 'postgresql'
14
- c.database = 'redding_ardb_test'
15
- c.encoding = 'unicode'
16
- c.min_messages = 'WARNING'
17
-
18
- c.logger = TEST_LOGGER
19
- c.root_path = File.join(TEST_SUPPORT_PATH, 'postgresql')
20
- c.migrations_path = 'migrations'
21
- c.schema_path = 'schema'
22
- c.schema_format = :ruby
23
- end
11
+ # we"re manually configuring ardb so we don"t need this to do anything
12
+ ENV["ARDB_DB_FILE"] = File.join(TEST_SUPPORT_PATH, "require_test_db_file")
13
+
14
+ @ardb_config =
15
+ Ardb::Config.new.tap do |c|
16
+ c.adapter = "postgresql"
17
+ c.database = "redding_ardb_test"
18
+ c.encoding = "unicode"
19
+ c.min_messages = "WARNING"
20
+
21
+ c.logger = TEST_LOGGER
22
+ c.root_path = File.join(TEST_SUPPORT_PATH, "postgresql")
23
+ c.migrations_path = "migrations"
24
+ c.schema_path = "schema"
25
+ c.schema_format = :ruby
26
+ end
24
27
  Assert.stub(Ardb, :config){ @ardb_config }
25
28
 
26
29
  Ardb.init(false)
@@ -33,7 +36,7 @@ class PostgresqlDbTests < Assert::Context
33
36
  teardown do
34
37
  Ardb.reset_adapter
35
38
  ActiveRecord::Base.logger = @orig_ar_logger
36
- ENV['ARDB_DB_FILE'] = @orig_env_ardb_db_file
39
+ ENV["ARDB_DB_FILE"] = @orig_env_ardb_db_file
37
40
  end
38
41
 
39
42
  private
@@ -41,12 +44,11 @@ class PostgresqlDbTests < Assert::Context
41
44
  # useful when testing creating/dropping/migrating DBs
42
45
  def silence_stdout
43
46
  current_stdout = $stdout.dup
44
- $stdout = File.new('/dev/null', 'w')
47
+ $stdout = File.new("/dev/null", "w")
45
48
  begin
46
49
  yield
47
50
  ensure
48
51
  $stdout = current_stdout
49
52
  end
50
53
  end
51
-
52
54
  end
@@ -1,2 +1,3 @@
1
+ # frozen_string_literal: true
1
2
  # this file is used to test that Ardb will relatively require a db file when
2
3
  # init
@@ -1 +1,2 @@
1
+ # frozen_string_literal: true
1
2
  # this file is used to test that Ardb will require a db file when init
data/test/system/.keep ADDED
File without changes