ardb 0.29.1 → 0.29.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.l.yml +8 -0
- data/.rubocop.yml +3 -0
- data/.t.yml +6 -0
- data/Gemfile +4 -2
- data/ardb.gemspec +9 -6
- data/bin/ardb +2 -0
- data/lib/ardb.rb +75 -61
- data/lib/ardb/adapter/base.rb +40 -19
- data/lib/ardb/adapter/mysql.rb +2 -0
- data/lib/ardb/adapter/postgresql.rb +36 -25
- data/lib/ardb/adapter/sqlite.rb +7 -7
- data/lib/ardb/adapter_spy.rb +16 -14
- data/lib/ardb/cli.rb +23 -18
- data/lib/ardb/cli/clirb.rb +5 -0
- data/lib/ardb/cli/commands.rb +184 -95
- data/lib/ardb/db_tests.rb +2 -0
- data/lib/ardb/default_order_by.rb +13 -11
- data/lib/ardb/migration.rb +7 -4
- data/lib/ardb/record_spy.rb +42 -38
- data/lib/ardb/relation_spy.rb +27 -25
- data/lib/ardb/require_autoloaded_active_record_files.rb +3 -1
- data/lib/ardb/test_helpers.rb +11 -9
- data/lib/ardb/use_db_default.rb +9 -7
- data/lib/ardb/version.rb +3 -1
- data/script/determine_autoloaded_active_record_files.rb +22 -20
- data/test/helper.rb +2 -0
- data/test/support/factory.rb +2 -1
- data/test/support/fake_schema.rb +3 -1
- data/test/support/postgresql/schema.rb +3 -1
- data/test/support/postgresql/setup_test_db.rb +3 -1
- data/test/support/relative_require_test_db_file.rb +1 -0
- data/test/support/require_test_db_file.rb +1 -0
- data/test/unit/adapter/base_tests.rb +9 -5
- data/test/unit/adapter/mysql_tests.rb +2 -0
- data/test/unit/adapter/postgresql_tests.rb +14 -14
- data/test/unit/adapter/sqlite_tests.rb +2 -0
- data/test/unit/adapter_spy_tests.rb +4 -1
- data/test/unit/ardb_tests.rb +28 -13
- data/test/unit/cli_tests.rb +47 -34
- data/test/unit/db_tests_tests.rb +4 -1
- data/test/unit/default_order_by_tests.rb +18 -13
- data/test/unit/migration_tests.rb +8 -5
- data/test/unit/record_spy_tests.rb +21 -14
- data/test/unit/relation_spy_tests.rb +28 -22
- data/test/unit/test_helpers_tests.rb +4 -1
- data/test/unit/use_db_default_tests.rb +16 -7
- metadata +27 -11
data/lib/ardb/db_tests.rb
CHANGED
@@ -1,26 +1,28 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "much-mixin"
|
2
4
|
|
3
5
|
module Ardb
|
4
6
|
module DefaultOrderBy
|
5
|
-
include
|
7
|
+
include MuchMixin
|
6
8
|
|
7
9
|
DEFAULT_ATTRIBUTE = :order_by
|
8
10
|
DEFAULT_SCOPE_PROC = proc{ self.class.scoped }
|
9
11
|
|
10
|
-
|
12
|
+
mixin_included do
|
11
13
|
@ardb_default_order_by_config = {}
|
12
14
|
end
|
13
15
|
|
14
|
-
|
16
|
+
mixin_class_methods do
|
15
17
|
def default_order_by(options = nil)
|
16
18
|
options ||= {}
|
17
19
|
|
18
20
|
@ardb_default_order_by_config.merge!({
|
19
|
-
:
|
20
|
-
:
|
21
|
+
attribute: options[:attribute] || DEFAULT_ATTRIBUTE,
|
22
|
+
scope_proc: options[:scope] || DEFAULT_SCOPE_PROC,
|
21
23
|
})
|
22
24
|
|
23
|
-
before_validation :ardb_default_order_by, :
|
25
|
+
before_validation :ardb_default_order_by, on: :create
|
24
26
|
end
|
25
27
|
|
26
28
|
def ardb_default_order_by_config
|
@@ -28,20 +30,20 @@ module Ardb
|
|
28
30
|
end
|
29
31
|
end
|
30
32
|
|
31
|
-
|
33
|
+
mixin_instance_methods do
|
32
34
|
private
|
33
35
|
|
34
36
|
def reset_order_by
|
35
37
|
attr_name = self.class.ardb_default_order_by_config[:attribute]
|
36
38
|
scope_proc = self.class.ardb_default_order_by_config[:scope_proc]
|
37
39
|
|
38
|
-
current_max =
|
39
|
-
|
40
|
+
current_max = instance_eval(&scope_proc).maximum(attr_name) || 0
|
41
|
+
send("#{attr_name}=", current_max + 1)
|
40
42
|
end
|
41
43
|
|
42
44
|
def ardb_default_order_by
|
43
45
|
attr_name = self.class.ardb_default_order_by_config[:attribute]
|
44
|
-
reset_order_by if
|
46
|
+
reset_order_by if send(attr_name).to_s.empty?
|
45
47
|
true
|
46
48
|
end
|
47
49
|
end
|
data/lib/ardb/migration.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "fileutils"
|
2
4
|
|
3
5
|
module Ardb
|
@@ -15,19 +17,20 @@ module Ardb
|
|
15
17
|
|
16
18
|
@class_name = @identifier.classify.pluralize
|
17
19
|
@file_name = get_file_name(@identifier)
|
18
|
-
@file_path = File.join(
|
20
|
+
@file_path = File.join(migrations_path, "#{@file_name}.rb")
|
19
21
|
|
20
22
|
migration_version = ActiveRecord::Migration.current_version
|
21
23
|
@source =
|
22
|
-
"class #{@class_name}
|
24
|
+
"class #{@class_name} "\
|
25
|
+
"< ActiveRecord::Migration[#{migration_version}]\n"\
|
23
26
|
" def change\n"\
|
24
27
|
" end\n"\
|
25
28
|
"end\n"
|
26
29
|
end
|
27
30
|
|
28
31
|
def save!
|
29
|
-
FileUtils.mkdir_p
|
30
|
-
File.open(
|
32
|
+
FileUtils.mkdir_p migrations_path
|
33
|
+
File.open(file_path, "w"){ |f| f.write(source) }
|
31
34
|
self
|
32
35
|
end
|
33
36
|
|
data/lib/ardb/record_spy.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "arel"
|
2
|
-
require "much-
|
4
|
+
require "much-mixin"
|
3
5
|
require "ardb/relation_spy"
|
4
6
|
|
5
7
|
module Ardb
|
6
8
|
module RecordSpy
|
7
|
-
include
|
9
|
+
include MuchMixin
|
8
10
|
|
9
11
|
def self.new(&block)
|
10
|
-
block ||= proc{
|
12
|
+
block ||= proc{}
|
11
13
|
record_spy = Class.new{ include Ardb::RecordSpy }
|
12
14
|
record_spy.class_eval(&block)
|
13
15
|
record_spy
|
@@ -15,7 +17,7 @@ module Ardb
|
|
15
17
|
|
16
18
|
CallbackType = Struct.new(:name, :options)
|
17
19
|
|
18
|
-
|
20
|
+
mixin_class_methods do
|
19
21
|
attr_accessor :table_name
|
20
22
|
|
21
23
|
# Associations
|
@@ -27,13 +29,14 @@ module Ardb
|
|
27
29
|
[:belongs_to, :has_one, :has_many].each do |method_name|
|
28
30
|
define_method(method_name) do |assoc_name, *args|
|
29
31
|
define_method(assoc_name) do
|
30
|
-
instance_variable_get("@#{assoc_name}") ||
|
32
|
+
instance_variable_get("@#{assoc_name}") ||
|
33
|
+
(method_name == :has_many ? [] : nil)
|
31
34
|
end
|
32
35
|
define_method("#{assoc_name}=") do |value|
|
33
36
|
instance_variable_set("@#{assoc_name}", value)
|
34
37
|
end
|
35
38
|
|
36
|
-
|
39
|
+
associations << Association.new(method_name, assoc_name, *args)
|
37
40
|
end
|
38
41
|
end
|
39
42
|
|
@@ -43,7 +46,8 @@ module Ardb
|
|
43
46
|
@validations ||= []
|
44
47
|
end
|
45
48
|
|
46
|
-
[
|
49
|
+
[
|
50
|
+
:validates_acceptance_of,
|
47
51
|
:validates_confirmation_of,
|
48
52
|
:validates_exclusion_of,
|
49
53
|
:validates_format_of,
|
@@ -52,29 +56,29 @@ module Ardb
|
|
52
56
|
:validates_numericality_of,
|
53
57
|
:validates_presence_of,
|
54
58
|
:validates_size_of,
|
55
|
-
:validates_uniqueness_of
|
59
|
+
:validates_uniqueness_of,
|
56
60
|
].each do |method_name|
|
57
61
|
type = method_name.to_s.match(/\Avalidates_(.+)_of\Z/)[1]
|
58
62
|
|
59
63
|
define_method(method_name) do |*args|
|
60
|
-
|
64
|
+
validations << Validation.new(type, *args)
|
61
65
|
end
|
62
66
|
end
|
63
67
|
|
64
68
|
def validates_associated(*args)
|
65
|
-
|
69
|
+
validations << Validation.new(:associated, *args)
|
66
70
|
end
|
67
71
|
|
68
72
|
def validates_with(*args)
|
69
|
-
|
73
|
+
validations << Validation.new(:with, *args)
|
70
74
|
end
|
71
75
|
|
72
76
|
def validates_each(*args, &block)
|
73
|
-
|
77
|
+
validations << Validation.new(:each, *args, &block)
|
74
78
|
end
|
75
79
|
|
76
80
|
def validate(method_name = nil, &block)
|
77
|
-
|
81
|
+
validations << Validation.new(:custom, method_name, &block)
|
78
82
|
end
|
79
83
|
|
80
84
|
def callbacks
|
@@ -83,7 +87,8 @@ module Ardb
|
|
83
87
|
|
84
88
|
# Callbacks
|
85
89
|
|
86
|
-
[
|
90
|
+
[
|
91
|
+
:before_validation,
|
87
92
|
:after_validation,
|
88
93
|
:before_create,
|
89
94
|
:around_create,
|
@@ -100,10 +105,10 @@ module Ardb
|
|
100
105
|
:after_commit,
|
101
106
|
:after_rollback,
|
102
107
|
:after_initialize,
|
103
|
-
:after_find
|
108
|
+
:after_find,
|
104
109
|
].each do |method_name|
|
105
110
|
define_method(method_name) do |*args, &block|
|
106
|
-
|
111
|
+
callbacks << Callback.new(method_name, *args, &block)
|
107
112
|
end
|
108
113
|
end
|
109
114
|
|
@@ -112,16 +117,16 @@ module Ardb
|
|
112
117
|
end
|
113
118
|
|
114
119
|
def define_model_callbacks(*args)
|
115
|
-
options = args.last.
|
120
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
116
121
|
types = options[:only] || [:before, :around, :after]
|
117
122
|
metaclass = class << self; self; end
|
118
123
|
|
119
124
|
args.each do |name|
|
120
|
-
|
125
|
+
custom_callback_types << CallbackType.new(name, options)
|
121
126
|
types.each do |type|
|
122
127
|
method_name = "#{type}_#{name}"
|
123
128
|
metaclass.send(:define_method, method_name) do |*args, &block|
|
124
|
-
|
129
|
+
callbacks << Callback.new(method_name, *args, &block)
|
125
130
|
end
|
126
131
|
end
|
127
132
|
end
|
@@ -135,14 +140,15 @@ module Ardb
|
|
135
140
|
end
|
136
141
|
|
137
142
|
def arel_table
|
138
|
-
@arel_table ||= Arel::Table.new(
|
143
|
+
@arel_table ||= Arel::Table.new(table_name)
|
139
144
|
end
|
140
145
|
|
141
146
|
def scoped
|
142
|
-
|
147
|
+
relation_spy
|
143
148
|
end
|
144
149
|
|
145
|
-
[
|
150
|
+
[
|
151
|
+
:select,
|
146
152
|
:from,
|
147
153
|
:includes,
|
148
154
|
:joins,
|
@@ -156,19 +162,19 @@ module Ardb
|
|
156
162
|
:offset,
|
157
163
|
:merge,
|
158
164
|
:except,
|
159
|
-
:only
|
165
|
+
:only,
|
160
166
|
].each do |method_name|
|
161
167
|
define_method(method_name) do |*args|
|
162
|
-
|
168
|
+
relation_spy.send(method_name, *args)
|
163
169
|
end
|
164
170
|
end
|
165
171
|
end
|
166
172
|
|
167
|
-
|
173
|
+
mixin_instance_methods do
|
168
174
|
attr_accessor :id
|
169
175
|
|
170
176
|
def update_column(col, value)
|
171
|
-
|
177
|
+
send("#{col}=", value)
|
172
178
|
end
|
173
179
|
|
174
180
|
def manually_run_callbacks
|
@@ -176,8 +182,8 @@ module Ardb
|
|
176
182
|
end
|
177
183
|
|
178
184
|
def run_callbacks(name, &block)
|
179
|
-
|
180
|
-
block
|
185
|
+
manually_run_callbacks << name
|
186
|
+
block&.call
|
181
187
|
end
|
182
188
|
end
|
183
189
|
|
@@ -195,8 +201,8 @@ module Ardb
|
|
195
201
|
attr_reader :type, :args, :options, :block
|
196
202
|
|
197
203
|
def initialize(type, *args, &block)
|
198
|
-
@type
|
199
|
-
@options = args.last.
|
204
|
+
@type = type.to_sym
|
205
|
+
@options = args.last.is_a?(::Hash) ? args.pop : {}
|
200
206
|
@args = args
|
201
207
|
@block = block
|
202
208
|
end
|
@@ -204,18 +210,16 @@ module Ardb
|
|
204
210
|
|
205
211
|
class Validation
|
206
212
|
attr_reader :type, :args, :options, :method_name, :block
|
207
|
-
|
208
|
-
|
209
|
-
|
213
|
+
alias_method :columns, :args
|
214
|
+
alias_method :associations, :args
|
215
|
+
alias_method :classes, :args
|
210
216
|
|
211
217
|
def initialize(type, *args, &block)
|
212
|
-
@type
|
213
|
-
@options = args.last.
|
218
|
+
@type = type.to_sym
|
219
|
+
@options = args.last.is_a?(::Hash) ? args.pop : {}
|
214
220
|
@args = args
|
215
221
|
@block = block
|
216
|
-
if @type == :custom
|
217
|
-
@method_name = @args.first
|
218
|
-
end
|
222
|
+
@method_name = @args.first if @type == :custom
|
219
223
|
end
|
220
224
|
end
|
221
225
|
end
|
data/lib/ardb/relation_spy.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Ardb
|
2
4
|
class RelationSpy
|
3
5
|
attr_reader :applied
|
@@ -21,7 +23,7 @@ module Ardb
|
|
21
23
|
end
|
22
24
|
|
23
25
|
def ==(other)
|
24
|
-
other.
|
26
|
+
other.is_a?(self.class) ? @applied == other.applied : super
|
25
27
|
end
|
26
28
|
|
27
29
|
def to_sql
|
@@ -37,17 +39,17 @@ module Ardb
|
|
37
39
|
|
38
40
|
# ActiveRecord::QueryMethods
|
39
41
|
|
40
|
-
[
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
42
|
+
[:select,
|
43
|
+
:from,
|
44
|
+
:includes,
|
45
|
+
:joins,
|
46
|
+
:where,
|
47
|
+
:group,
|
48
|
+
:having,
|
49
|
+
:order,
|
50
|
+
:reverse_order,
|
51
|
+
:readonly,
|
52
|
+
].each do |type|
|
51
53
|
define_method(type) do |*args|
|
52
54
|
@applied << AppliedExpression.new(type, args)
|
53
55
|
self
|
@@ -56,31 +58,31 @@ module Ardb
|
|
56
58
|
|
57
59
|
def limit(value)
|
58
60
|
@limit_value = value ? value.to_i : nil
|
59
|
-
@applied << AppliedExpression.new(:limit, [
|
61
|
+
@applied << AppliedExpression.new(:limit, [value])
|
60
62
|
self
|
61
63
|
end
|
62
64
|
|
63
65
|
def offset(value)
|
64
66
|
@offset_value = value ? value.to_i : nil
|
65
|
-
@applied << AppliedExpression.new(:offset, [
|
67
|
+
@applied << AppliedExpression.new(:offset, [value])
|
66
68
|
self
|
67
69
|
end
|
68
70
|
|
69
71
|
# ActiveRecord::SpawnMethods
|
70
72
|
|
71
73
|
def merge(other)
|
72
|
-
return self if
|
73
|
-
if other.
|
74
|
-
other.applied.each{ |a|
|
74
|
+
return self if equal?(other)
|
75
|
+
if other.is_a?(self.class)
|
76
|
+
other.applied.each{ |a| send(a.type, *a.args) }
|
75
77
|
else
|
76
|
-
@applied << AppliedExpression.new(:merge, [
|
78
|
+
@applied << AppliedExpression.new(:merge, [other])
|
77
79
|
end
|
78
80
|
self
|
79
81
|
end
|
80
82
|
|
81
83
|
def except(*skips)
|
82
84
|
skips = skips.map(&:to_sym)
|
83
|
-
|
85
|
+
dup.tap do |r|
|
84
86
|
r.applied.reject!{ |a| skips.include?(a.type) }
|
85
87
|
r.limit_value = nil if skips.include?(:limit)
|
86
88
|
r.offset_value = nil if skips.include?(:offset)
|
@@ -89,7 +91,7 @@ module Ardb
|
|
89
91
|
|
90
92
|
def only(*onlies)
|
91
93
|
onlies = onlies.map(&:to_sym)
|
92
|
-
|
94
|
+
dup.tap do |r|
|
93
95
|
r.applied.reject!{ |a| !onlies.include?(a.type) }
|
94
96
|
r.limit_value = nil unless onlies.include?(:limit)
|
95
97
|
r.offset_value = nil unless onlies.include?(:offset)
|
@@ -104,19 +106,19 @@ module Ardb
|
|
104
106
|
end
|
105
107
|
|
106
108
|
def first
|
107
|
-
|
109
|
+
all.first
|
108
110
|
end
|
109
111
|
|
110
112
|
def first!
|
111
|
-
|
113
|
+
first || raise(NotFoundError)
|
112
114
|
end
|
113
115
|
|
114
116
|
def last
|
115
|
-
|
117
|
+
all.last
|
116
118
|
end
|
117
119
|
|
118
120
|
def last!
|
119
|
-
|
121
|
+
last || raise(NotFoundError)
|
120
122
|
end
|
121
123
|
|
122
124
|
def all
|
@@ -143,7 +145,7 @@ module Ardb
|
|
143
145
|
|
144
146
|
class AppliedExpression < Struct.new(:type, :args)
|
145
147
|
def to_sql
|
146
|
-
"#{
|
148
|
+
"#{type}: #{args.inspect}"
|
147
149
|
end
|
148
150
|
end
|
149
151
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# ActiveRecord makes use of autoload to load some of its components as-needed.
|
2
4
|
# This doesn"t work well with threaded environments, and causes uninitialized
|
3
5
|
# constants. To avoid this, this file manually requires the following files that
|
@@ -173,7 +175,7 @@ elsif ActiveRecord.version.segments[0] == 5
|
|
173
175
|
else
|
174
176
|
raise(
|
175
177
|
"ActiveRecord #{ActiveRecord.version} isn't supported. "\
|
176
|
-
"Switch to 5.X or 6.X"
|
178
|
+
"Switch to 5.X or 6.X",
|
177
179
|
)
|
178
180
|
end
|
179
181
|
|