temporal_tables 2.0.0 → 3.0.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/.github/workflows/test.yml +35 -12
- data/.rubocop.yml +30 -146
- data/.ruby-version +1 -1
- data/README.md +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/association_extensions.rb +14 -2
- data/lib/temporal_tables/constants.rb +1 -0
- data/lib/temporal_tables/temporal_adapter.rb +3 -2
- data/lib/temporal_tables/temporal_class.rb +2 -2
- data/lib/temporal_tables/version.rb +1 -1
- data/lib/temporal_tables.rb +1 -6
- data/spec/basic_history_spec.rb +51 -2
- data/spec/internal/app/models/bird/nest.rb +6 -0
- data/spec/internal/app/models/bird.rb +5 -0
- data/spec/internal/app/models/person.rb +1 -1
- data/spec/internal/db/schema.rb +9 -0
- data/spec/spec_helper.rb +1 -1
- data/temporal_tables.gemspec +6 -4
- metadata +49 -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
|
|
@@ -10,12 +10,24 @@ module TemporalTables
|
|
|
10
10
|
# Using responds_to? results in an infinite loop stack overflow.
|
|
11
11
|
if @owner.public_methods.include?(:at_value)
|
|
12
12
|
# If this is a history record but no at time was given,
|
|
13
|
-
# assume the record's effective to date
|
|
14
|
-
|
|
13
|
+
# assume the record's effective to date minus 1 microsecond
|
|
14
|
+
# The logic here is to provide the association's history record at the end of
|
|
15
|
+
# the parent record's effective period. Since effective ranges are exclusive of
|
|
16
|
+
# the eff_to value, and the eff_* columns are datetime types with a precision of microseconds,
|
|
17
|
+
# 1 microsecond before eff_to is the end of the inclusive boundary to accomplish this.
|
|
18
|
+
super.at(@owner.at_value || (@owner.eff_to - TemporalTables::ONE_MICROSECOND))
|
|
15
19
|
else
|
|
16
20
|
super
|
|
17
21
|
end
|
|
18
22
|
end
|
|
23
|
+
|
|
24
|
+
# There seems to be an issue with the statement cache for history associations.
|
|
25
|
+
# This may be due to the at_value not being part of how the relations are hashed,
|
|
26
|
+
# or that the cached statements are not parameterized. Will require further investigation.
|
|
27
|
+
# In the meantime, we can workaround this issue by disabling the statement cache for History queries.
|
|
28
|
+
def skip_statement_cache?(scope)
|
|
29
|
+
klass.is_a?(TemporalTables::TemporalClass::ClassMethods) || super(scope)
|
|
30
|
+
end
|
|
19
31
|
end
|
|
20
32
|
end
|
|
21
33
|
|
|
@@ -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
|
|
@@ -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
|
|
@@ -77,7 +77,7 @@ module TemporalTables
|
|
|
77
77
|
# An object at a given time should fall within the range, excluding the effective end date.
|
|
78
78
|
# However, when using '9999-12-31', this is effectively infinity and should not be excluded.
|
|
79
79
|
def build_temporal_constraint(at_value)
|
|
80
|
-
|
|
80
|
+
arel_table[:eff_to].gt(at_value).or(arel_table[:eff_to].eq(TemporalTables::END_OF_TIME)).and(
|
|
81
81
|
arel_table[:eff_from].lteq(at_value)
|
|
82
82
|
)
|
|
83
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'
|
|
@@ -23,11 +22,7 @@ module TemporalTables
|
|
|
23
22
|
# It's necessary to do this on the implementations in order for the
|
|
24
23
|
# alias method chain hooks to work.
|
|
25
24
|
ActiveRecord::ConnectionAdapters::AbstractAdapter.subclasses.each do |subclass|
|
|
26
|
-
|
|
27
|
-
subclass.send :prepend, TemporalTables::TemporalAdapterSixOh
|
|
28
|
-
else
|
|
29
|
-
subclass.send :prepend, TemporalTables::TemporalAdapter
|
|
30
|
-
end
|
|
25
|
+
subclass.send :prepend, TemporalTables::TemporalAdapter
|
|
31
26
|
|
|
32
27
|
module_name = subclass.name.split('::').last
|
|
33
28
|
next unless TemporalTables::ConnectionAdapters.const_defined?(module_name)
|
data/spec/basic_history_spec.rb
CHANGED
|
@@ -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!
|
|
@@ -201,7 +216,7 @@ describe Person do
|
|
|
201
216
|
expect(dog_at_moment_of_name_change.first.name).to eq('Max')
|
|
202
217
|
end
|
|
203
218
|
|
|
204
|
-
context 'Max is rehomed' do
|
|
219
|
+
context 'when Max is rehomed' do
|
|
205
220
|
before do
|
|
206
221
|
dog.destroy!
|
|
207
222
|
end
|
|
@@ -214,4 +229,38 @@ describe Person do
|
|
|
214
229
|
end
|
|
215
230
|
end
|
|
216
231
|
end
|
|
232
|
+
|
|
233
|
+
describe 'when removing a creature' do
|
|
234
|
+
let!(:wart) { Wart.create person: emily, hairiness: 3 }
|
|
235
|
+
|
|
236
|
+
before do
|
|
237
|
+
emily.destroy!
|
|
238
|
+
sleep 0.1
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
it 'destroys associated warts and we remember the historical association' do
|
|
242
|
+
expect(emily).to be_destroyed
|
|
243
|
+
expect { wart.reload }.to raise_error(ActiveRecord::RecordNotFound) # as it belonged to emily
|
|
244
|
+
|
|
245
|
+
wart_h = wart.history.last # the last version of the wart
|
|
246
|
+
expect(wart_h).to be_present
|
|
247
|
+
|
|
248
|
+
emily_h = wart_h.person
|
|
249
|
+
expect(emily_h).to be_present # we should be able to tell what person our wart belonged to
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
describe Bird do
|
|
255
|
+
context 'when a bird and nest exist' do
|
|
256
|
+
let(:bird) { Bird.create name: 'Sam' }
|
|
257
|
+
let(:nest) { Bird::Nest.create bird: bird, height: 100 }
|
|
258
|
+
|
|
259
|
+
it 'can create instance of class with nested class name with history entries' do
|
|
260
|
+
expect(bird).not_to be_nil
|
|
261
|
+
expect(nest).not_to be_nil
|
|
262
|
+
expect(bird.history.first).not_to be_nil
|
|
263
|
+
expect(nest.history.first).not_to be_nil
|
|
264
|
+
end
|
|
265
|
+
end
|
|
217
266
|
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.
|
|
27
|
+
gem.add_dependency 'rails', '>= 6.1', '< 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
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: temporal_tables
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brent Kroeker
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-01-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -16,20 +16,20 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '6.
|
|
19
|
+
version: '6.1'
|
|
20
20
|
- - "<"
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
|
-
version: '7.
|
|
22
|
+
version: '7.2'
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
26
|
requirements:
|
|
27
27
|
- - ">="
|
|
28
28
|
- !ruby/object:Gem::Version
|
|
29
|
-
version: '6.
|
|
29
|
+
version: '6.1'
|
|
30
30
|
- - "<"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '7.
|
|
32
|
+
version: '7.2'
|
|
33
33
|
- !ruby/object:Gem::Dependency
|
|
34
34
|
name: combustion
|
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -64,14 +64,14 @@ dependencies:
|
|
|
64
64
|
requirements:
|
|
65
65
|
- - "~>"
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: '0.
|
|
67
|
+
version: '0.8'
|
|
68
68
|
type: :development
|
|
69
69
|
prerelease: false
|
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
|
71
71
|
requirements:
|
|
72
72
|
- - "~>"
|
|
73
73
|
- !ruby/object:Gem::Version
|
|
74
|
-
version: '0.
|
|
74
|
+
version: '0.8'
|
|
75
75
|
- !ruby/object:Gem::Dependency
|
|
76
76
|
name: mysql2
|
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -142,6 +142,34 @@ dependencies:
|
|
|
142
142
|
- - ">="
|
|
143
143
|
- !ruby/object:Gem::Version
|
|
144
144
|
version: '0'
|
|
145
|
+
- !ruby/object:Gem::Dependency
|
|
146
|
+
name: rubocop-rails
|
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
|
148
|
+
requirements:
|
|
149
|
+
- - ">="
|
|
150
|
+
- !ruby/object:Gem::Version
|
|
151
|
+
version: '0'
|
|
152
|
+
type: :development
|
|
153
|
+
prerelease: false
|
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
155
|
+
requirements:
|
|
156
|
+
- - ">="
|
|
157
|
+
- !ruby/object:Gem::Version
|
|
158
|
+
version: '0'
|
|
159
|
+
- !ruby/object:Gem::Dependency
|
|
160
|
+
name: rubocop-rspec
|
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
|
162
|
+
requirements:
|
|
163
|
+
- - ">="
|
|
164
|
+
- !ruby/object:Gem::Version
|
|
165
|
+
version: '0'
|
|
166
|
+
type: :development
|
|
167
|
+
prerelease: false
|
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
169
|
+
requirements:
|
|
170
|
+
- - ">="
|
|
171
|
+
- !ruby/object:Gem::Version
|
|
172
|
+
version: '0'
|
|
145
173
|
description: |2
|
|
146
174
|
Easily recall what your data looked like at any point in the past!
|
|
147
175
|
TemporalTables sets up and maintains history tables to track all temporal changes to to your data.
|
|
@@ -156,16 +184,11 @@ files:
|
|
|
156
184
|
- ".gitignore"
|
|
157
185
|
- ".rubocop.yml"
|
|
158
186
|
- ".ruby-version"
|
|
159
|
-
- ".travis.yml"
|
|
160
187
|
- Gemfile
|
|
161
188
|
- LICENSE.txt
|
|
162
189
|
- README.md
|
|
163
190
|
- Rakefile
|
|
164
191
|
- config.ru
|
|
165
|
-
- gemfiles/Gemfile.6.0.mysql
|
|
166
|
-
- gemfiles/Gemfile.6.0.mysql.lock
|
|
167
|
-
- gemfiles/Gemfile.6.0.pg
|
|
168
|
-
- gemfiles/Gemfile.6.0.pg.lock
|
|
169
192
|
- gemfiles/Gemfile.6.1.mysql
|
|
170
193
|
- gemfiles/Gemfile.6.1.mysql.lock
|
|
171
194
|
- gemfiles/Gemfile.6.1.pg
|
|
@@ -174,6 +197,10 @@ files:
|
|
|
174
197
|
- gemfiles/Gemfile.7.0.mysql.lock
|
|
175
198
|
- gemfiles/Gemfile.7.0.pg
|
|
176
199
|
- gemfiles/Gemfile.7.0.pg.lock
|
|
200
|
+
- gemfiles/Gemfile.7.1.mysql
|
|
201
|
+
- gemfiles/Gemfile.7.1.mysql.lock
|
|
202
|
+
- gemfiles/Gemfile.7.1.pg
|
|
203
|
+
- gemfiles/Gemfile.7.1.pg.lock
|
|
177
204
|
- lib/temporal_tables.rb
|
|
178
205
|
- lib/temporal_tables/arel_table.rb
|
|
179
206
|
- lib/temporal_tables/association_extensions.rb
|
|
@@ -185,11 +212,12 @@ files:
|
|
|
185
212
|
- lib/temporal_tables/reflection_extensions.rb
|
|
186
213
|
- lib/temporal_tables/relation_extensions.rb
|
|
187
214
|
- lib/temporal_tables/temporal_adapter.rb
|
|
188
|
-
- lib/temporal_tables/temporal_adapter_six_oh.rb
|
|
189
215
|
- lib/temporal_tables/temporal_class.rb
|
|
190
216
|
- lib/temporal_tables/version.rb
|
|
191
217
|
- lib/temporal_tables/whodunnit.rb
|
|
192
218
|
- spec/basic_history_spec.rb
|
|
219
|
+
- spec/internal/app/models/bird.rb
|
|
220
|
+
- spec/internal/app/models/bird/nest.rb
|
|
193
221
|
- spec/internal/app/models/broom.rb
|
|
194
222
|
- spec/internal/app/models/cat.rb
|
|
195
223
|
- spec/internal/app/models/cat_life.rb
|
|
@@ -211,7 +239,7 @@ homepage: ''
|
|
|
211
239
|
licenses: []
|
|
212
240
|
metadata:
|
|
213
241
|
rubygems_mfa_required: 'true'
|
|
214
|
-
post_install_message:
|
|
242
|
+
post_install_message:
|
|
215
243
|
rdoc_options: []
|
|
216
244
|
require_paths:
|
|
217
245
|
- lib
|
|
@@ -219,19 +247,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
219
247
|
requirements:
|
|
220
248
|
- - ">="
|
|
221
249
|
- !ruby/object:Gem::Version
|
|
222
|
-
version:
|
|
250
|
+
version: 3.0.0
|
|
223
251
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
224
252
|
requirements:
|
|
225
253
|
- - ">="
|
|
226
254
|
- !ruby/object:Gem::Version
|
|
227
255
|
version: '0'
|
|
228
256
|
requirements: []
|
|
229
|
-
rubygems_version: 3.
|
|
230
|
-
signing_key:
|
|
257
|
+
rubygems_version: 3.4.10
|
|
258
|
+
signing_key:
|
|
231
259
|
specification_version: 4
|
|
232
260
|
summary: Tracks all history of changes to a table automatically in a history table.
|
|
233
261
|
test_files:
|
|
234
262
|
- spec/basic_history_spec.rb
|
|
263
|
+
- spec/internal/app/models/bird.rb
|
|
264
|
+
- spec/internal/app/models/bird/nest.rb
|
|
235
265
|
- spec/internal/app/models/broom.rb
|
|
236
266
|
- spec/internal/app/models/cat.rb
|
|
237
267
|
- spec/internal/app/models/cat_life.rb
|