temporal_tables 3.0.0.pre.rc.1 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 31e81d8469855b4283e3a56ef636df6c13866fc68327e1b8795ce22e09682a23
4
- data.tar.gz: 3d5d3d9cb10a01573bb52edacf2941612545443c1af19e275f181578a8e11678
3
+ metadata.gz: 263d71547d60d6a668202ad900b21ee8d683615dd4afc096e37a9d9a53489b33
4
+ data.tar.gz: acc012e82bd6deae7872b22fb80ee8d6dbea27cf53f73dd9b87fb303015540ce
5
5
  SHA512:
6
- metadata.gz: ac18fbf6c986bd41d3ec0804d203ef54f042304c693017e69b3885129ac344e7401cdac59903fdc9d6deb3cc77273f051a6f175da317be8fac7505b2b1b88b5a
7
- data.tar.gz: 0c6d6cb23559785e115afb4fadf9d9d7af4d1565971aa78dde486a3cfee3538809ad99117e1d2d5d792da681a6cb8db22d0451ce787755e94f90bdceb1ddec7d
6
+ metadata.gz: f4543bec2427c87c59f2c0df7edea2fbaa6072ae583584c8bbcf54ea60e8de2e03ec290c0375ba91608a0cd32aec00ac11106ae0391b8632b03f60170dcffdd5
7
+ data.tar.gz: 0dc70cd60fc891be32c8f22f440bf3ed6ede26c5c1e6b5f028d3930166c1fcb92df528930364d0e8983bb9dd9128596ea2b64f5d48efd5c3af1373d1f2505e4a
@@ -4,6 +4,8 @@ on:
4
4
  push:
5
5
  branches:
6
6
  - '**'
7
+ tags:
8
+ - "v*.*.*"
7
9
  pull_request:
8
10
  branches:
9
11
  - master
@@ -44,7 +46,7 @@ jobs:
44
46
  ruby-version: "${{ matrix.ruby }}"
45
47
  - name: Bundle
46
48
  run: |
47
- gem install bundler:2.2.15
49
+ gem install bundler:2.4.10
48
50
  bundle install
49
51
 
50
52
  - name: Run Rubocop
@@ -55,3 +57,20 @@ jobs:
55
57
  PGHOST: localhost
56
58
  PGUSER: postgres
57
59
  run: bundle exec rspec
60
+
61
+ publish:
62
+ needs: [tests]
63
+ runs-on: ubuntu-latest
64
+ if: startsWith(github.ref, 'refs/tags/v')
65
+
66
+ permissions:
67
+ contents: write
68
+ id-token: write
69
+
70
+ steps:
71
+ - uses: actions/checkout@v2
72
+ - uses: ruby/setup-ruby@v1
73
+ with:
74
+ ruby-version: "3.2.2"
75
+ bundler-cache: true
76
+ - uses: rubygems/release-gem@v1
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![Actions Status](https://github.com/bkroeker/temporal_tables/workflows/Continuous%20Integration/badge.svg?branch=master)](https://github.com/bkroeker/temporal_tables/actions)
1
+ [![Continuous Integration](https://github.com/bkroeker/temporal_tables/actions/workflows/test.yml/badge.svg)](https://github.com/bkroeker/temporal_tables/actions/workflows/test.yml)
2
2
 
3
3
  # TemporalTables
4
4
 
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- temporal_tables (3.0.0)
5
- rails (>= 6.0, < 7.2)
4
+ temporal_tables (3.0.1)
5
+ rails (>= 6.1, < 7.2)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- temporal_tables (3.0.0)
5
- rails (>= 6.0, < 7.2)
4
+ temporal_tables (3.0.1)
5
+ rails (>= 6.1, < 7.2)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- temporal_tables (3.0.0)
5
- rails (>= 6.0, < 7.2)
4
+ temporal_tables (3.0.1)
5
+ rails (>= 6.1, < 7.2)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- temporal_tables (3.0.0)
5
- rails (>= 6.0, < 7.2)
4
+ temporal_tables (3.0.1)
5
+ rails (>= 6.1, < 7.2)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- temporal_tables (3.0.0)
5
- rails (>= 6.0, < 7.2)
4
+ temporal_tables (3.0.1)
5
+ rails (>= 6.1, < 7.2)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- temporal_tables (3.0.0)
5
- rails (>= 6.0, < 7.2)
4
+ temporal_tables (3.0.1)
5
+ rails (>= 6.1, < 7.2)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -10,8 +10,12 @@ 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
- super.at(@owner.at_value || @owner.eff_to)
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
@@ -2,4 +2,5 @@
2
2
 
3
3
  module TemporalTables
4
4
  END_OF_TIME = '9999-12-31'
5
+ ONE_MICROSECOND = 0.000001.seconds
5
6
  end
@@ -42,8 +42,7 @@ module TemporalTables
42
42
  association.macro, association.name,
43
43
  **association.options.merge(
44
44
  class_name: clazz.name,
45
- foreign_key: association.foreign_key,
46
- primary_key: clazz.orig_class.primary_key
45
+ foreign_key: association.foreign_key
47
46
  )
48
47
  )
49
48
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TemporalTables
4
- VERSION = '3.0.0-rc.1'
4
+ VERSION = '3.0.1'
5
5
  end
@@ -229,6 +229,26 @@ describe Person do
229
229
  end
230
230
  end
231
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
232
252
  end
233
253
 
234
254
  describe Bird do
@@ -244,3 +264,19 @@ describe Bird do
244
264
  end
245
265
  end
246
266
  end
267
+
268
+ describe Hamster do
269
+ context 'with tables that have non-default primary key names' do
270
+ let(:hamster) { Hamster.create name: 'Fluffy' }
271
+ let(:wheel) { HamsterWheel.create hamster: hamster }
272
+
273
+ it 'can create instance of class with nested class name with history entries' do
274
+ expect(hamster).not_to be_nil
275
+ expect(wheel).not_to be_nil
276
+ expect(hamster.hamster_wheel).not_to be_nil
277
+ hamster_history = Hamster.history.at(Time.now.utc).first
278
+ expect(hamster_history).not_to be_nil
279
+ expect(hamster_history.hamster_wheel).not_to be_nil
280
+ end
281
+ end
282
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Hamster < ActiveRecord::Base
4
+ self.primary_key = :uuid
5
+
6
+ has_one :hamster_wheel, foreign_key: :hamster_uuid, inverse_of: :hamster
7
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class HamsterWheel < ActiveRecord::Base
4
+ belongs_to :hamster, foreign_key: :hamster_uuid, primary_key: :uuid, inverse_of: :hamster_wheel
5
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  class Person < ActiveRecord::Base
4
4
  belongs_to :coven
5
- has_many :warts
5
+ has_many :warts, dependent: :destroy
6
6
  has_many :flying_machines
7
7
  end
@@ -69,4 +69,22 @@ ActiveRecord::Schema.define do
69
69
  t.belongs_to :bird, type: (postgres ? :uuid : :integer)
70
70
  t.integer :height
71
71
  end
72
+
73
+ if postgres
74
+ create_table :hamsters, id: false do |t|
75
+ t.column :uuid, :uuid, default: 'gen_random_uuid()'
76
+ t.string :name
77
+ end
78
+ execute 'ALTER TABLE hamsters ADD PRIMARY KEY (uuid);'
79
+ add_temporal_table :hamsters
80
+ else
81
+ create_table :hamsters, primary_key: :uuid, temporal: true do |t|
82
+ t.string :name
83
+ end
84
+ end
85
+
86
+ create_table :hamster_wheels, id: (postgres ? :uuid : :integer), temporal: true do |t|
87
+ t.column :hamster_uuid, (postgres ? :uuid : :bigint), null: false
88
+ t.foreign_key :hamsters, column: :hamster_uuid, primary_key: :uuid
89
+ end
72
90
  end
@@ -24,7 +24,7 @@ Gem::Specification.new do |gem|
24
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.2'
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
30
  gem.add_development_dependency 'gemika', '~> 0.8'
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: 3.0.0.pre.rc.1
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brent Kroeker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-08 00:00:00.000000000 Z
11
+ date: 2024-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '6.0'
19
+ version: '6.1'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '7.2'
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '6.0'
29
+ version: '6.1'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '7.2'
@@ -224,6 +224,8 @@ files:
224
224
  - spec/internal/app/models/coven.rb
225
225
  - spec/internal/app/models/dog.rb
226
226
  - spec/internal/app/models/flying_machine.rb
227
+ - spec/internal/app/models/hamster.rb
228
+ - spec/internal/app/models/hamster_wheel.rb
227
229
  - spec/internal/app/models/person.rb
228
230
  - spec/internal/app/models/rocket_broom.rb
229
231
  - spec/internal/app/models/wart.rb
@@ -250,9 +252,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
250
252
  version: 3.0.0
251
253
  required_rubygems_version: !ruby/object:Gem::Requirement
252
254
  requirements:
253
- - - ">"
255
+ - - ">="
254
256
  - !ruby/object:Gem::Version
255
- version: 1.3.1
257
+ version: '0'
256
258
  requirements: []
257
259
  rubygems_version: 3.4.10
258
260
  signing_key:
@@ -268,6 +270,8 @@ test_files:
268
270
  - spec/internal/app/models/coven.rb
269
271
  - spec/internal/app/models/dog.rb
270
272
  - spec/internal/app/models/flying_machine.rb
273
+ - spec/internal/app/models/hamster.rb
274
+ - spec/internal/app/models/hamster_wheel.rb
271
275
  - spec/internal/app/models/person.rb
272
276
  - spec/internal/app/models/rocket_broom.rb
273
277
  - spec/internal/app/models/wart.rb