temporal_tables 1.1.0 → 3.0.0.pre.rc.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.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +15 -11
- data/.rubocop.yml +30 -146
- data/.ruby-version +1 -1
- data/gemfiles/Gemfile.6.1.mysql +3 -0
- data/gemfiles/Gemfile.6.1.mysql.lock +147 -87
- data/gemfiles/Gemfile.6.1.pg +3 -0
- data/gemfiles/Gemfile.6.1.pg.lock +148 -88
- data/gemfiles/Gemfile.7.0.mysql +3 -0
- data/gemfiles/Gemfile.7.0.mysql.lock +150 -84
- data/gemfiles/Gemfile.7.0.pg +3 -0
- data/gemfiles/Gemfile.7.0.pg.lock +151 -85
- data/gemfiles/{Gemfile.6.0.mysql → Gemfile.7.1.mysql} +4 -1
- data/gemfiles/Gemfile.7.1.mysql.lock +266 -0
- data/gemfiles/{Gemfile.6.0.pg → Gemfile.7.1.pg} +4 -1
- data/gemfiles/Gemfile.7.1.pg.lock +266 -0
- data/lib/temporal_tables/arel_table.rb +1 -1
- data/lib/temporal_tables/association_extensions.rb +8 -0
- data/lib/temporal_tables/connection_adapters/mysql_adapter.rb +2 -2
- data/lib/temporal_tables/connection_adapters/postgresql_adapter.rb +2 -2
- data/lib/temporal_tables/constants.rb +5 -0
- data/lib/temporal_tables/temporal_adapter.rb +4 -3
- data/lib/temporal_tables/temporal_class.rb +4 -2
- data/lib/temporal_tables/version.rb +1 -1
- data/lib/temporal_tables.rb +2 -6
- data/spec/basic_history_spec.rb +39 -4
- data/spec/internal/app/models/bird/nest.rb +6 -0
- data/spec/internal/app/models/bird.rb +5 -0
- data/spec/internal/db/schema.rb +9 -0
- data/spec/spec_helper.rb +1 -1
- data/temporal_tables.gemspec +6 -4
- metadata +50 -19
- data/.travis.yml +0 -11
- data/gemfiles/Gemfile.6.0.mysql.lock +0 -171
- data/gemfiles/Gemfile.6.0.pg.lock +0 -176
- data/lib/temporal_tables/temporal_adapter_six_oh.rb +0 -207
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: ..
|
|
3
|
+
specs:
|
|
4
|
+
temporal_tables (3.0.0)
|
|
5
|
+
rails (>= 6.0, < 7.2)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
actioncable (7.1.2)
|
|
11
|
+
actionpack (= 7.1.2)
|
|
12
|
+
activesupport (= 7.1.2)
|
|
13
|
+
nio4r (~> 2.0)
|
|
14
|
+
websocket-driver (>= 0.6.1)
|
|
15
|
+
zeitwerk (~> 2.6)
|
|
16
|
+
actionmailbox (7.1.2)
|
|
17
|
+
actionpack (= 7.1.2)
|
|
18
|
+
activejob (= 7.1.2)
|
|
19
|
+
activerecord (= 7.1.2)
|
|
20
|
+
activestorage (= 7.1.2)
|
|
21
|
+
activesupport (= 7.1.2)
|
|
22
|
+
mail (>= 2.7.1)
|
|
23
|
+
net-imap
|
|
24
|
+
net-pop
|
|
25
|
+
net-smtp
|
|
26
|
+
actionmailer (7.1.2)
|
|
27
|
+
actionpack (= 7.1.2)
|
|
28
|
+
actionview (= 7.1.2)
|
|
29
|
+
activejob (= 7.1.2)
|
|
30
|
+
activesupport (= 7.1.2)
|
|
31
|
+
mail (~> 2.5, >= 2.5.4)
|
|
32
|
+
net-imap
|
|
33
|
+
net-pop
|
|
34
|
+
net-smtp
|
|
35
|
+
rails-dom-testing (~> 2.2)
|
|
36
|
+
actionpack (7.1.2)
|
|
37
|
+
actionview (= 7.1.2)
|
|
38
|
+
activesupport (= 7.1.2)
|
|
39
|
+
nokogiri (>= 1.8.5)
|
|
40
|
+
racc
|
|
41
|
+
rack (>= 2.2.4)
|
|
42
|
+
rack-session (>= 1.0.1)
|
|
43
|
+
rack-test (>= 0.6.3)
|
|
44
|
+
rails-dom-testing (~> 2.2)
|
|
45
|
+
rails-html-sanitizer (~> 1.6)
|
|
46
|
+
actiontext (7.1.2)
|
|
47
|
+
actionpack (= 7.1.2)
|
|
48
|
+
activerecord (= 7.1.2)
|
|
49
|
+
activestorage (= 7.1.2)
|
|
50
|
+
activesupport (= 7.1.2)
|
|
51
|
+
globalid (>= 0.6.0)
|
|
52
|
+
nokogiri (>= 1.8.5)
|
|
53
|
+
actionview (7.1.2)
|
|
54
|
+
activesupport (= 7.1.2)
|
|
55
|
+
builder (~> 3.1)
|
|
56
|
+
erubi (~> 1.11)
|
|
57
|
+
rails-dom-testing (~> 2.2)
|
|
58
|
+
rails-html-sanitizer (~> 1.6)
|
|
59
|
+
activejob (7.1.2)
|
|
60
|
+
activesupport (= 7.1.2)
|
|
61
|
+
globalid (>= 0.3.6)
|
|
62
|
+
activemodel (7.1.2)
|
|
63
|
+
activesupport (= 7.1.2)
|
|
64
|
+
activerecord (7.1.2)
|
|
65
|
+
activemodel (= 7.1.2)
|
|
66
|
+
activesupport (= 7.1.2)
|
|
67
|
+
timeout (>= 0.4.0)
|
|
68
|
+
activestorage (7.1.2)
|
|
69
|
+
actionpack (= 7.1.2)
|
|
70
|
+
activejob (= 7.1.2)
|
|
71
|
+
activerecord (= 7.1.2)
|
|
72
|
+
activesupport (= 7.1.2)
|
|
73
|
+
marcel (~> 1.0)
|
|
74
|
+
activesupport (7.1.2)
|
|
75
|
+
base64
|
|
76
|
+
bigdecimal
|
|
77
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
78
|
+
connection_pool (>= 2.2.5)
|
|
79
|
+
drb
|
|
80
|
+
i18n (>= 1.6, < 2)
|
|
81
|
+
minitest (>= 5.1)
|
|
82
|
+
mutex_m
|
|
83
|
+
tzinfo (~> 2.0)
|
|
84
|
+
ast (2.4.2)
|
|
85
|
+
base64 (0.2.0)
|
|
86
|
+
bigdecimal (3.1.5)
|
|
87
|
+
builder (3.2.4)
|
|
88
|
+
byebug (11.1.3)
|
|
89
|
+
combustion (1.3.7)
|
|
90
|
+
activesupport (>= 3.0.0)
|
|
91
|
+
railties (>= 3.0.0)
|
|
92
|
+
thor (>= 0.14.6)
|
|
93
|
+
concurrent-ruby (1.2.2)
|
|
94
|
+
connection_pool (2.4.1)
|
|
95
|
+
crass (1.0.6)
|
|
96
|
+
database_cleaner (2.0.2)
|
|
97
|
+
database_cleaner-active_record (>= 2, < 3)
|
|
98
|
+
database_cleaner-active_record (2.1.0)
|
|
99
|
+
activerecord (>= 5.a)
|
|
100
|
+
database_cleaner-core (~> 2.0.0)
|
|
101
|
+
database_cleaner-core (2.0.1)
|
|
102
|
+
date (3.3.4)
|
|
103
|
+
diff-lcs (1.5.0)
|
|
104
|
+
drb (2.2.0)
|
|
105
|
+
ruby2_keywords
|
|
106
|
+
erubi (1.12.0)
|
|
107
|
+
gemika (0.8.2)
|
|
108
|
+
globalid (1.2.1)
|
|
109
|
+
activesupport (>= 6.1)
|
|
110
|
+
i18n (1.14.1)
|
|
111
|
+
concurrent-ruby (~> 1.0)
|
|
112
|
+
io-console (0.7.1)
|
|
113
|
+
irb (1.11.0)
|
|
114
|
+
rdoc
|
|
115
|
+
reline (>= 0.3.8)
|
|
116
|
+
json (2.7.1)
|
|
117
|
+
language_server-protocol (3.17.0.3)
|
|
118
|
+
loofah (2.22.0)
|
|
119
|
+
crass (~> 1.0.2)
|
|
120
|
+
nokogiri (>= 1.12.0)
|
|
121
|
+
mail (2.8.1)
|
|
122
|
+
mini_mime (>= 0.1.1)
|
|
123
|
+
net-imap
|
|
124
|
+
net-pop
|
|
125
|
+
net-smtp
|
|
126
|
+
marcel (1.0.2)
|
|
127
|
+
mini_mime (1.1.5)
|
|
128
|
+
minitest (5.20.0)
|
|
129
|
+
mutex_m (0.2.0)
|
|
130
|
+
net-imap (0.4.9)
|
|
131
|
+
date
|
|
132
|
+
net-protocol
|
|
133
|
+
net-pop (0.1.2)
|
|
134
|
+
net-protocol
|
|
135
|
+
net-protocol (0.2.2)
|
|
136
|
+
timeout
|
|
137
|
+
net-smtp (0.4.0)
|
|
138
|
+
net-protocol
|
|
139
|
+
nio4r (2.7.0)
|
|
140
|
+
nokogiri (1.16.0-x86_64-linux)
|
|
141
|
+
racc (~> 1.4)
|
|
142
|
+
parallel (1.24.0)
|
|
143
|
+
parser (3.3.0.0)
|
|
144
|
+
ast (~> 2.4.1)
|
|
145
|
+
racc
|
|
146
|
+
pg (1.5.4)
|
|
147
|
+
psych (5.1.2)
|
|
148
|
+
stringio
|
|
149
|
+
racc (1.7.3)
|
|
150
|
+
rack (3.0.8)
|
|
151
|
+
rack-session (2.0.0)
|
|
152
|
+
rack (>= 3.0.0)
|
|
153
|
+
rack-test (2.1.0)
|
|
154
|
+
rack (>= 1.3)
|
|
155
|
+
rackup (2.1.0)
|
|
156
|
+
rack (>= 3)
|
|
157
|
+
webrick (~> 1.8)
|
|
158
|
+
rails (7.1.2)
|
|
159
|
+
actioncable (= 7.1.2)
|
|
160
|
+
actionmailbox (= 7.1.2)
|
|
161
|
+
actionmailer (= 7.1.2)
|
|
162
|
+
actionpack (= 7.1.2)
|
|
163
|
+
actiontext (= 7.1.2)
|
|
164
|
+
actionview (= 7.1.2)
|
|
165
|
+
activejob (= 7.1.2)
|
|
166
|
+
activemodel (= 7.1.2)
|
|
167
|
+
activerecord (= 7.1.2)
|
|
168
|
+
activestorage (= 7.1.2)
|
|
169
|
+
activesupport (= 7.1.2)
|
|
170
|
+
bundler (>= 1.15.0)
|
|
171
|
+
railties (= 7.1.2)
|
|
172
|
+
rails-dom-testing (2.2.0)
|
|
173
|
+
activesupport (>= 5.0.0)
|
|
174
|
+
minitest
|
|
175
|
+
nokogiri (>= 1.6)
|
|
176
|
+
rails-html-sanitizer (1.6.0)
|
|
177
|
+
loofah (~> 2.21)
|
|
178
|
+
nokogiri (~> 1.14)
|
|
179
|
+
railties (7.1.2)
|
|
180
|
+
actionpack (= 7.1.2)
|
|
181
|
+
activesupport (= 7.1.2)
|
|
182
|
+
irb
|
|
183
|
+
rackup (>= 1.0.0)
|
|
184
|
+
rake (>= 12.2)
|
|
185
|
+
thor (~> 1.0, >= 1.2.2)
|
|
186
|
+
zeitwerk (~> 2.6)
|
|
187
|
+
rainbow (3.1.1)
|
|
188
|
+
rake (13.1.0)
|
|
189
|
+
rdoc (6.6.2)
|
|
190
|
+
psych (>= 4.0.0)
|
|
191
|
+
regexp_parser (2.8.3)
|
|
192
|
+
reline (0.4.1)
|
|
193
|
+
io-console (~> 0.5)
|
|
194
|
+
rexml (3.2.6)
|
|
195
|
+
rspec (3.12.0)
|
|
196
|
+
rspec-core (~> 3.12.0)
|
|
197
|
+
rspec-expectations (~> 3.12.0)
|
|
198
|
+
rspec-mocks (~> 3.12.0)
|
|
199
|
+
rspec-core (3.12.2)
|
|
200
|
+
rspec-support (~> 3.12.0)
|
|
201
|
+
rspec-expectations (3.12.3)
|
|
202
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
203
|
+
rspec-support (~> 3.12.0)
|
|
204
|
+
rspec-mocks (3.12.6)
|
|
205
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
206
|
+
rspec-support (~> 3.12.0)
|
|
207
|
+
rspec-support (3.12.1)
|
|
208
|
+
rubocop (1.59.0)
|
|
209
|
+
json (~> 2.3)
|
|
210
|
+
language_server-protocol (>= 3.17.0)
|
|
211
|
+
parallel (~> 1.10)
|
|
212
|
+
parser (>= 3.2.2.4)
|
|
213
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
214
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
215
|
+
rexml (>= 3.2.5, < 4.0)
|
|
216
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
|
217
|
+
ruby-progressbar (~> 1.7)
|
|
218
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
|
219
|
+
rubocop-ast (1.30.0)
|
|
220
|
+
parser (>= 3.2.1.0)
|
|
221
|
+
rubocop-capybara (2.20.0)
|
|
222
|
+
rubocop (~> 1.41)
|
|
223
|
+
rubocop-factory_bot (2.25.0)
|
|
224
|
+
rubocop (~> 1.33)
|
|
225
|
+
rubocop-rails (2.23.1)
|
|
226
|
+
activesupport (>= 4.2.0)
|
|
227
|
+
rack (>= 1.1)
|
|
228
|
+
rubocop (>= 1.33.0, < 2.0)
|
|
229
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
|
230
|
+
rubocop-rspec (2.26.1)
|
|
231
|
+
rubocop (~> 1.40)
|
|
232
|
+
rubocop-capybara (~> 2.17)
|
|
233
|
+
rubocop-factory_bot (~> 2.22)
|
|
234
|
+
ruby-progressbar (1.13.0)
|
|
235
|
+
ruby2_keywords (0.0.5)
|
|
236
|
+
stringio (3.1.0)
|
|
237
|
+
thor (1.3.0)
|
|
238
|
+
timeout (0.4.1)
|
|
239
|
+
tzinfo (2.0.6)
|
|
240
|
+
concurrent-ruby (~> 1.0)
|
|
241
|
+
unicode-display_width (2.5.0)
|
|
242
|
+
webrick (1.8.1)
|
|
243
|
+
websocket-driver (0.7.6)
|
|
244
|
+
websocket-extensions (>= 0.1.0)
|
|
245
|
+
websocket-extensions (0.1.5)
|
|
246
|
+
zeitwerk (2.6.12)
|
|
247
|
+
|
|
248
|
+
PLATFORMS
|
|
249
|
+
x86_64-linux
|
|
250
|
+
|
|
251
|
+
DEPENDENCIES
|
|
252
|
+
byebug
|
|
253
|
+
combustion
|
|
254
|
+
database_cleaner
|
|
255
|
+
gemika
|
|
256
|
+
pg (>= 0.18, < 2.0)
|
|
257
|
+
rails (~> 7.1.0)
|
|
258
|
+
rake
|
|
259
|
+
rspec (~> 3.4)
|
|
260
|
+
rubocop
|
|
261
|
+
rubocop-rails
|
|
262
|
+
rubocop-rspec
|
|
263
|
+
temporal_tables!
|
|
264
|
+
|
|
265
|
+
BUNDLED WITH
|
|
266
|
+
2.4.10
|
|
@@ -16,6 +16,14 @@ module TemporalTables
|
|
|
16
16
|
super
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
|
+
|
|
20
|
+
# There seems to be an issue with the statement cache for history associations.
|
|
21
|
+
# This may be due to the at_value not being part of how the relations are hashed,
|
|
22
|
+
# or that the cached statements are not parameterized. Will require further investigation.
|
|
23
|
+
# In the meantime, we can workaround this issue by disabling the statement cache for History queries.
|
|
24
|
+
def skip_statement_cache?(scope)
|
|
25
|
+
klass.is_a?(TemporalTables::TemporalClass::ClassMethods) || super(scope)
|
|
26
|
+
end
|
|
19
27
|
end
|
|
20
28
|
end
|
|
21
29
|
|
|
@@ -34,7 +34,7 @@ module TemporalTables
|
|
|
34
34
|
|
|
35
35
|
update #{temporal_name(table_name)} set eff_to = @current_time
|
|
36
36
|
where #{primary_key} = new.#{primary_key}
|
|
37
|
-
and eff_to = '
|
|
37
|
+
and eff_to = '#{TemporalTables::END_OF_TIME}';
|
|
38
38
|
|
|
39
39
|
insert into #{temporal_name(table_name)} (#{column_names.join(', ')}, eff_from)
|
|
40
40
|
values (#{column_names.collect { |c| "new.#{c}" }.join(', ')}, @current_time);
|
|
@@ -51,7 +51,7 @@ module TemporalTables
|
|
|
51
51
|
|
|
52
52
|
update #{temporal_name(table_name)} set eff_to = @current_time
|
|
53
53
|
where #{primary_key} = old.#{primary_key}
|
|
54
|
-
and eff_to = '
|
|
54
|
+
and eff_to = '#{TemporalTables::END_OF_TIME}';
|
|
55
55
|
|
|
56
56
|
end
|
|
57
57
|
}
|
|
@@ -40,7 +40,7 @@ module TemporalTables
|
|
|
40
40
|
|
|
41
41
|
update #{temporal_name(table_name)} set eff_to = cur_time
|
|
42
42
|
where #{primary_key} = new.#{primary_key}
|
|
43
|
-
and eff_to = '
|
|
43
|
+
and eff_to = '#{TemporalTables::END_OF_TIME}';
|
|
44
44
|
|
|
45
45
|
insert into #{temporal_name(table_name)} (#{column_list(column_names)}, eff_from)
|
|
46
46
|
values (#{column_names.collect { |c| "new.#{c}" }.join(', ')}, cur_time);
|
|
@@ -63,7 +63,7 @@ module TemporalTables
|
|
|
63
63
|
|
|
64
64
|
update #{temporal_name(table_name)} set eff_to = cur_time
|
|
65
65
|
where #{primary_key} = old.#{primary_key}
|
|
66
|
-
and eff_to = '
|
|
66
|
+
and eff_to = '#{TemporalTables::END_OF_TIME}';
|
|
67
67
|
|
|
68
68
|
return null;
|
|
69
69
|
end
|
|
@@ -5,12 +5,13 @@ require 'digest'
|
|
|
5
5
|
module TemporalTables
|
|
6
6
|
module TemporalAdapter # rubocop:disable Metrics/ModuleLength
|
|
7
7
|
def create_table(table_name, **options, &block) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
|
8
|
+
valid_options = options.except(:temporal, :temporal_bypass)
|
|
8
9
|
if options[:temporal_bypass]
|
|
9
|
-
super(table_name, **
|
|
10
|
+
super(table_name, **valid_options, &block)
|
|
10
11
|
else
|
|
11
12
|
skip_table = TemporalTables.skipped_temporal_tables.include?(table_name.to_sym) || table_name.to_s =~ /_h$/
|
|
12
13
|
|
|
13
|
-
super(table_name, **
|
|
14
|
+
super(table_name, **valid_options) do |t|
|
|
14
15
|
block.call t
|
|
15
16
|
|
|
16
17
|
if TemporalTables.add_updated_by_field && !skip_table
|
|
@@ -35,7 +36,7 @@ module TemporalTables
|
|
|
35
36
|
**options.merge(id: false, primary_key: 'history_id', temporal_bypass: true)
|
|
36
37
|
) do |t|
|
|
37
38
|
t.datetime :eff_from, null: false, limit: 6
|
|
38
|
-
t.datetime :eff_to, null: false, limit: 6, default:
|
|
39
|
+
t.datetime :eff_to, null: false, limit: 6, default: TemporalTables::END_OF_TIME
|
|
39
40
|
|
|
40
41
|
columns(table_name).each do |c|
|
|
41
42
|
column_options = { limit: c.limit }
|
|
@@ -33,7 +33,7 @@ module TemporalTables
|
|
|
33
33
|
|
|
34
34
|
# Calling .history here will ensure that the history class
|
|
35
35
|
# for this association is created and initialized
|
|
36
|
-
clazz = association.
|
|
36
|
+
clazz = association.klass.history
|
|
37
37
|
|
|
38
38
|
# Recreate the association, updating it to point at the
|
|
39
39
|
# history class. The foreign key is explicitly set since it's
|
|
@@ -74,8 +74,10 @@ module TemporalTables
|
|
|
74
74
|
|
|
75
75
|
delegate :descends_from_active_record?, to: :superclass
|
|
76
76
|
|
|
77
|
+
# An object at a given time should fall within the range, excluding the effective end date.
|
|
78
|
+
# However, when using '9999-12-31', this is effectively infinity and should not be excluded.
|
|
77
79
|
def build_temporal_constraint(at_value)
|
|
78
|
-
arel_table[:eff_to].
|
|
80
|
+
arel_table[:eff_to].gt(at_value).or(arel_table[:eff_to].eq(TemporalTables::END_OF_TIME)).and(
|
|
79
81
|
arel_table[:eff_from].lteq(at_value)
|
|
80
82
|
)
|
|
81
83
|
end
|
data/lib/temporal_tables.rb
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'temporal_tables/temporal_adapter'
|
|
4
|
-
require 'temporal_tables/temporal_adapter_six_oh'
|
|
5
4
|
require 'temporal_tables/connection_adapters/mysql_adapter'
|
|
6
5
|
require 'temporal_tables/connection_adapters/postgresql_adapter'
|
|
7
6
|
require 'temporal_tables/whodunnit'
|
|
@@ -12,6 +11,7 @@ require 'temporal_tables/association_extensions'
|
|
|
12
11
|
require 'temporal_tables/preloader_extensions'
|
|
13
12
|
require 'temporal_tables/reflection_extensions'
|
|
14
13
|
require 'temporal_tables/arel_table'
|
|
14
|
+
require 'temporal_tables/constants'
|
|
15
15
|
require 'temporal_tables/version'
|
|
16
16
|
|
|
17
17
|
module TemporalTables
|
|
@@ -22,11 +22,7 @@ module TemporalTables
|
|
|
22
22
|
# It's necessary to do this on the implementations in order for the
|
|
23
23
|
# alias method chain hooks to work.
|
|
24
24
|
ActiveRecord::ConnectionAdapters::AbstractAdapter.subclasses.each do |subclass|
|
|
25
|
-
|
|
26
|
-
subclass.send :prepend, TemporalTables::TemporalAdapterSixOh
|
|
27
|
-
else
|
|
28
|
-
subclass.send :prepend, TemporalTables::TemporalAdapter
|
|
29
|
-
end
|
|
25
|
+
subclass.send :prepend, TemporalTables::TemporalAdapter
|
|
30
26
|
|
|
31
27
|
module_name = subclass.name.split('::').last
|
|
32
28
|
next unless TemporalTables::ConnectionAdapters.const_defined?(module_name)
|
data/spec/basic_history_spec.rb
CHANGED
|
@@ -90,10 +90,10 @@ describe Person do
|
|
|
90
90
|
where = sql[4]
|
|
91
91
|
|
|
92
92
|
expect(from.scan(/.warts_h.\..eff_from./i).count).to eq(1)
|
|
93
|
-
expect(from.scan(/.warts_h.\..eff_to./i).count).to eq(
|
|
93
|
+
expect(from.scan(/.warts_h.\..eff_to./i).count).to eq(2)
|
|
94
94
|
|
|
95
95
|
expect(where.scan(/.people_h.\..eff_from./i).count).to eq(1)
|
|
96
|
-
expect(where.scan(/.people_h.\..eff_to./i).count).to eq(
|
|
96
|
+
expect(where.scan(/.people_h.\..eff_to./i).count).to eq(2)
|
|
97
97
|
expect(where.scan(/.warts_h.\..eff_from./i).count).to eq(0)
|
|
98
98
|
expect(where.scan(/.warts_h.\..eff_to./i).count).to eq(0)
|
|
99
99
|
end
|
|
@@ -132,6 +132,21 @@ describe Person do
|
|
|
132
132
|
end
|
|
133
133
|
end
|
|
134
134
|
|
|
135
|
+
# This test is to cover the StatementCache issue being worked around by the monkey patch in AssociationExtensions
|
|
136
|
+
describe 'when making multiple association queries with different at values for different data' do
|
|
137
|
+
it 'the correct data should be returned' do
|
|
138
|
+
sabrina = Person.create name: 'Sabrina'
|
|
139
|
+
sabrina_wart = Wart.create person: sabrina
|
|
140
|
+
sabrina_wart.history.at(Time.current).first.person
|
|
141
|
+
|
|
142
|
+
willow = Person.create name: 'Willow'
|
|
143
|
+
willow_wart = Wart.create person: willow
|
|
144
|
+
current_willow = willow_wart.history.at(Time.current).first.person
|
|
145
|
+
|
|
146
|
+
expect(current_willow.name).to eq('Willow')
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
135
150
|
describe 'when working with STI one level deep' do
|
|
136
151
|
let!(:broom) { Broom.create person: emily, model: 'Cackler 2000' }
|
|
137
152
|
|
|
@@ -180,7 +195,7 @@ describe Person do
|
|
|
180
195
|
describe 'when spawning and renaming a creature with PK not named id' do
|
|
181
196
|
let!(:dog) { Dog.create name: 'Fido' }
|
|
182
197
|
|
|
183
|
-
context 'Fido is renamed to Max' do
|
|
198
|
+
context 'when Fido is renamed to Max' do
|
|
184
199
|
before do
|
|
185
200
|
dog.name = 'Max'
|
|
186
201
|
dog.save!
|
|
@@ -195,7 +210,13 @@ describe Person do
|
|
|
195
210
|
expect(fido.orig_obj.name).to eq('Max')
|
|
196
211
|
end
|
|
197
212
|
|
|
198
|
-
|
|
213
|
+
it 'at the exact time of the name change, the dog should not be both Max and Fido' do
|
|
214
|
+
dog_at_moment_of_name_change = dog.history.at(dog.history.last.eff_from)
|
|
215
|
+
expect(dog_at_moment_of_name_change.count).to eq(1)
|
|
216
|
+
expect(dog_at_moment_of_name_change.first.name).to eq('Max')
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
context 'when Max is rehomed' do
|
|
199
220
|
before do
|
|
200
221
|
dog.destroy!
|
|
201
222
|
end
|
|
@@ -209,3 +230,17 @@ describe Person do
|
|
|
209
230
|
end
|
|
210
231
|
end
|
|
211
232
|
end
|
|
233
|
+
|
|
234
|
+
describe Bird do
|
|
235
|
+
context 'when a bird and nest exist' do
|
|
236
|
+
let(:bird) { Bird.create name: 'Sam' }
|
|
237
|
+
let(:nest) { Bird::Nest.create bird: bird, height: 100 }
|
|
238
|
+
|
|
239
|
+
it 'can create instance of class with nested class name with history entries' do
|
|
240
|
+
expect(bird).not_to be_nil
|
|
241
|
+
expect(nest).not_to be_nil
|
|
242
|
+
expect(bird.history.first).not_to be_nil
|
|
243
|
+
expect(nest.history.first).not_to be_nil
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
data/spec/internal/db/schema.rb
CHANGED
|
@@ -60,4 +60,13 @@ ActiveRecord::Schema.define do
|
|
|
60
60
|
create_table :a_very_very_very_very_very_long_table_name, temporal: true do |t|
|
|
61
61
|
t.string :name
|
|
62
62
|
end
|
|
63
|
+
|
|
64
|
+
create_table :birds, id: (postgres ? :uuid : :integer), temporal: true, force: true do |t|
|
|
65
|
+
t.string :name
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
create_table :nests, id: (postgres ? :uuid : :integer), temporal: true do |t|
|
|
69
|
+
t.belongs_to :bird, type: (postgres ? :uuid : :integer)
|
|
70
|
+
t.integer :height
|
|
71
|
+
end
|
|
63
72
|
end
|
data/spec/spec_helper.rb
CHANGED
data/temporal_tables.gemspec
CHANGED
|
@@ -5,7 +5,7 @@ lib = File.expand_path('lib', __dir__)
|
|
|
5
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
6
6
|
require 'temporal_tables/version'
|
|
7
7
|
|
|
8
|
-
Gem::Specification.new do |gem|
|
|
8
|
+
Gem::Specification.new do |gem|
|
|
9
9
|
gem.name = 'temporal_tables'
|
|
10
10
|
gem.version = TemporalTables::VERSION
|
|
11
11
|
gem.authors = ['Brent Kroeker']
|
|
@@ -21,17 +21,19 @@ Gem::Specification.new do |gem| # rubocop:disable Metrics/BlockLength
|
|
|
21
21
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
|
22
22
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
23
23
|
gem.require_paths = ['lib']
|
|
24
|
-
gem.required_ruby_version = '>=
|
|
24
|
+
gem.required_ruby_version = '>= 3.0.0'
|
|
25
25
|
gem.metadata = { 'rubygems_mfa_required' => 'true' }
|
|
26
26
|
|
|
27
|
-
gem.add_dependency 'rails', '>= 6.0', '< 7.
|
|
27
|
+
gem.add_dependency 'rails', '>= 6.0', '< 7.2'
|
|
28
28
|
gem.add_development_dependency 'combustion', '~> 1'
|
|
29
29
|
gem.add_development_dependency 'database_cleaner'
|
|
30
|
-
gem.add_development_dependency 'gemika', '~> 0.
|
|
30
|
+
gem.add_development_dependency 'gemika', '~> 0.8'
|
|
31
31
|
gem.add_development_dependency 'mysql2'
|
|
32
32
|
gem.add_development_dependency 'pg'
|
|
33
33
|
gem.add_development_dependency 'pry'
|
|
34
34
|
gem.add_development_dependency 'rspec', '~> 3.4'
|
|
35
35
|
gem.add_development_dependency 'rubocop'
|
|
36
|
+
gem.add_development_dependency 'rubocop-rails'
|
|
37
|
+
gem.add_development_dependency 'rubocop-rspec'
|
|
36
38
|
gem.metadata['rubygems_mfa_required'] = 'true'
|
|
37
39
|
end
|