sequel_bitemporal 0.9.1 → 0.11.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f6daa2d7f025cd1281e8cbfc7235d0a6ddd85d2251f8d9195d85cc5340aafb3
4
- data.tar.gz: 5d5de257ee011436a1c3959206c31c985d6b11597d63fcab468876865394f9ee
3
+ metadata.gz: 33df8e3ea5762139cd17bc15469b6f4c0535e698191eff1db9feb1387be4eb9b
4
+ data.tar.gz: da3482ad1fa5d018fc50e95c45940beba6013205574f65257be300abbfc119ee
5
5
  SHA512:
6
- metadata.gz: '0309ac260a37ec550e417efb01eaa72120583a5c26c6306f52c15910d36c8dc24f9e74d39319f763e3a566192ddd5887b0b022ce747f820beee388a444726dc8'
7
- data.tar.gz: f4f61ba42c6510bcc744f96a27ca9a91fe965762ce4ec6206720441346ec1e5402475e27e87a7b838d342898c47df99a1e8025abf5ebce59691250417bc0015f
6
+ metadata.gz: 0b6f966365eaf5c42143b5e050c467aaef0b1e479c68fd792cbedc1cf4d3c420962651254ca9dd1344c95e4401f3ee2ba56f6acb54702248a8d4d5684d351265
7
+ data.tar.gz: 176b15f045e9b91b29857f0b5e1ffcbb313d44cd623bd10718cbdabd359ba929b55c231882d639e47499c496307c8b5bbf9c160cacc11569d46c624bca9439d3
@@ -0,0 +1,64 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: ['**']
8
+
9
+ jobs:
10
+ tests:
11
+ services:
12
+ postgres:
13
+ image: postgres:13
14
+ env:
15
+ POSTGRES_USER: postgres
16
+ POSTGRES_PASSWORD: postgres
17
+ ports:
18
+ - 5432
19
+ options: >-
20
+ --health-cmd pg_isready
21
+ --health-interval 10s
22
+ --health-timeout 5s
23
+ --health-retries 5
24
+
25
+ runs-on: ubuntu-latest
26
+ strategy:
27
+ fail-fast: false
28
+ matrix:
29
+ ruby:
30
+ - "2.7"
31
+ - "3.0"
32
+ - "3.1"
33
+ - "3.2"
34
+ - "3.3"
35
+ name: Ruby ${{ matrix.ruby }}
36
+
37
+ env:
38
+ SEQUEL: "~> 5.0"
39
+ BUNDLE_GEMFILE: "ci/sequel.gemfile"
40
+ steps:
41
+ - uses: actions/checkout@v3
42
+ - name: Install db dependencies and check connections
43
+ run: |
44
+ env PGPASSWORD=postgres psql -h localhost -p ${{ job.services.postgres.ports[5432] }} -U postgres -l
45
+ - uses: ruby/setup-ruby@v1
46
+ with:
47
+ ruby-version: ${{ matrix.ruby }}
48
+ bundler-cache: true
49
+ - name: Create databases
50
+ run: |
51
+ env PGPASSWORD=postgres psql -c 'create database sequel_bitemporal_test;' -U postgres -h localhost -p ${{ job.services.postgres.ports[5432] }}
52
+ - name: Run PostgreSQL tests
53
+ run: bundle exec rake spec
54
+ env:
55
+ TEST_ADAPTER: postgresql
56
+ TEST_DATABASE: sequel_bitemporal_test
57
+ TEST_DATABASE_HOST: localhost
58
+ TEST_DATABASE_PORT: ${{ job.services.postgres.ports[5432] }}
59
+ TEST_USERNAME: postgres
60
+ TEST_PASSWORD: postgres
61
+ - name: Run SQLite tests
62
+ run: bundle exec rake spec
63
+ env:
64
+ TEST_ADAPTER: sqlite
data/README.md CHANGED
@@ -14,29 +14,37 @@ Dependencies
14
14
  Usage
15
15
  -----
16
16
 
17
- * Declare bitemporality inside your model:
17
+ Declare bitemporality inside your model:
18
18
 
19
- class HotelPriceVersion < Sequel::Model
20
- end
19
+ ```ruby
20
+ class HotelPriceVersion < Sequel::Model
21
+ end
21
22
 
22
- class HotelPrice < Sequel::Model
23
- plugin :bitemporal, version_class: HotelPriceVersion
24
- end
23
+ class HotelPrice < Sequel::Model
24
+ plugin :bitemporal, version_class: HotelPriceVersion
25
+ end
26
+ ```
25
27
 
26
- * You can now create a hotel price with bitemporal versions:
28
+ You can now create a hotel price with bitemporal versions:
27
29
 
28
- price = HotelPrice.new
29
- price.update_attributes price: 18
30
+ ```ruby
31
+ price = HotelPrice.new
32
+ price.update_attributes price: 18
33
+ ```
30
34
 
31
- * To show all versions:
35
+ To show all versions:
32
36
 
33
- price.versions
37
+ ```ruby
38
+ price.versions
39
+ ```
34
40
 
35
- * To get current version:
41
+ To show current version:
36
42
 
37
- price.current_version
43
+ ```ruby
44
+ price.current_version
45
+ ```
38
46
 
39
- * Look at the specs for more usage patterns.
47
+ Look at the specs for more usage patterns.
40
48
 
41
49
  Thanks
42
50
  ------
@@ -48,7 +56,17 @@ Thanks to Ksenia Zalesnaya (@ksenia-zalesnaya) for her contributions:
48
56
  - define setter methods for versioned columns
49
57
 
50
58
  Thanks to Denis Kalesnikov (@DenisKem) for his contributions:
51
- - allow composite primary key
59
+ - add support for composite primary key
60
+ [#8](https://github.com/TalentBox/sequel_bitemporal/pull/8)
61
+
62
+ Thanks to Olle Jonsson (@olleolleolle) for his contributions:
63
+ - update specs to work with RSpec: `config.disable_monkey_patching!`
64
+ [#10](https://github.com/TalentBox/sequel_bitemporal/pull/10)
65
+ - update TravisCI matrix to include more Ruby versions
66
+ [#11](https://github.com/TalentBox/sequel_bitemporal/pull/10)
67
+ - README improvements
68
+ [#9](https://github.com/TalentBox/sequel_bitemporal/pull/9)
69
+ [#12](https://github.com/TalentBox/sequel_bitemporal/pull/12)
52
70
 
53
71
  License
54
72
  -------
@@ -332,9 +332,9 @@ module Sequel
332
332
  { master_id: id }
333
333
  end
334
334
 
335
- current_version.keys.each do |key|
335
+ current_version.columns.each do |key|
336
336
  next if excluded_columns.include? key
337
- current_attributes[key] = current_version.send key
337
+ current_attributes[key] = current_version.public_send key
338
338
  end if current_version?
339
339
  model.version_class.new current_attributes
340
340
  end
@@ -469,7 +469,7 @@ module Sequel
469
469
  last_version_attributes = if last_version
470
470
  last_version.columns.each_with_object({}) do |column, hash|
471
471
  unless excluded_columns.include? column
472
- hash[column] = last_version.send column
472
+ hash[column] = last_version.public_send column
473
473
  end
474
474
  end
475
475
  else
@@ -539,33 +539,28 @@ module Sequel
539
539
  to_check_columns = self.class.version_class.columns - excluded_columns
540
540
  updated_by = (send(self.class.audit_updated_by_method) if audited?)
541
541
  previous_values = @current_version_values || {}
542
- current_version_values = {}
543
- columns = pending_version.columns - excluded_columns_for_changes
544
- columns.each do |column|
545
- current_version_values[column] = pending_version.public_send(column)
546
- end
547
-
542
+ current_values = values_for_changes pending_version
548
543
  futures.each do |future_version|
549
544
  attrs = {}
550
545
  to_check_columns.each do |col|
551
546
  if previous_values[col]==future_version[col] &&
552
- previous_values[col]!=current_version_values[col]
553
- attrs[col] = current_version_values[col]
547
+ previous_values[col]!=current_values[col]
548
+ attrs[col] = current_values[col]
554
549
  end
555
550
  end
556
551
  if attrs.any?
557
552
  propagated = save_propagated future_version, attrs
553
+ previous_values = values_for_changes future_version
554
+ current_values = values_for_changes propagated
558
555
  if !propagated.new? && audited? && updated_by
559
556
  self.class.audit_class.audit(
560
557
  self,
561
- future_version.values,
562
- propagated.values,
558
+ previous_values,
559
+ current_values,
563
560
  propagated.valid_from,
564
561
  updated_by
565
562
  )
566
563
  end
567
- previous_values = future_version.values.dup
568
- current_version_values = propagated.values
569
564
  future_version.this.update :expired_at => Sequel::Plugins::Bitemporal.point_in_time
570
565
  else
571
566
  break
@@ -583,7 +578,7 @@ module Sequel
583
578
  self.class.audit_class.audit(
584
579
  self,
585
580
  current_values_for_audit,
586
- pending_version.values,
581
+ values_for_changes(pending_version),
587
582
  pending_version.valid_from,
588
583
  updated_by
589
584
  ) if updated_by
@@ -597,8 +592,8 @@ module Sequel
597
592
 
598
593
  def save_fossil(expired, attributes={})
599
594
  fossil = model.version_class.new
600
- expired_attributes = expired.keys.each_with_object({}) do |key, hash|
601
- hash[key] = expired.send key
595
+ expired_attributes = expired.columns.each_with_object({}) do |key, hash|
596
+ hash[key] = expired.public_send key
602
597
  end
603
598
  expired_attributes.delete :id
604
599
  fossil.set_all expired_attributes.merge(attributes)
@@ -608,8 +603,8 @@ module Sequel
608
603
 
609
604
  def save_propagated(version, attributes={})
610
605
  propagated = model.version_class.new
611
- version_attributes = version.keys.each_with_object({}) do |key, hash|
612
- hash[key] = version.send key
606
+ version_attributes = version.columns.each_with_object({}) do |key, hash|
607
+ hash[key] = version.public_send key
613
608
  end
614
609
  version_attributes.delete :id
615
610
  version_attributes[:created_at] = Sequel::Plugins::Bitemporal.point_in_time
@@ -627,10 +622,8 @@ module Sequel
627
622
  def pending_version_holds_changes?
628
623
  return false unless @pending_version
629
624
  return true unless current_version?
630
- @current_version_values = current_version.values
631
- columns = pending_version.columns - excluded_columns_for_changes
632
- columns.detect do |column|
633
- new_value = pending_version.send column
625
+ @current_version_values = values_for_changes current_version
626
+ values_for_changes(pending_version).any? do |column, new_value|
634
627
  case column
635
628
  when :id, :created_at, :expired_at, *version_foreign_keys
636
629
  false
@@ -653,7 +646,7 @@ module Sequel
653
646
  new_value = model.version_class.input_transformers[:string_nilifier].call(new_value)
654
647
  end
655
648
  end
656
- current_version.send(column)!=new_value
649
+ current_version.public_send(column)!=new_value
657
650
  end
658
651
  end
659
652
  end
@@ -670,6 +663,14 @@ module Sequel
670
663
  @initial_version ||= model.version_class.new
671
664
  end
672
665
 
666
+ def values_for_changes(version)
667
+ values = {}
668
+ (version.columns - excluded_columns_for_changes).each do |column|
669
+ values[column] = version.public_send column
670
+ end
671
+ values
672
+ end
673
+
673
674
  end
674
675
  end
675
676
  end
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "sequel_bitemporal"
6
- s.version = "0.9.1"
6
+ s.version = "0.11.0"
7
7
  s.authors = ["Joseph HALTER", "Jonathan TRON"]
8
8
  s.email = ["joseph.halter@thetalentbox.com", "jonathan.tron@thetalentbox.com"]
9
9
  s.homepage = "https://github.com/TalentBox/sequel_bitemporal"
@@ -72,4 +72,42 @@ RSpec.describe "Sequel::Plugins::Bitemporal", :skip_jdbc_sqlite do
72
72
  end
73
73
  end
74
74
 
75
+ it "can propage changes to future version per column with defaults" do
76
+ propagate_per_column = @master_class.propagate_per_column
77
+ begin
78
+ @master_class.instance_variable_set :@propagate_per_column, true
79
+ @version_class.class_eval do
80
+ define_method :name do
81
+ super() || {}
82
+ end
83
+ end
84
+ master = @master_class.new
85
+ expect( master.name ).to eql({})
86
+ expect( master.save ).to be_truthy
87
+ @version_class.create master_id: master.id, valid_from: Date.parse("2016-01-01"), valid_to: Date.parse("2017-01-01"), price: 0
88
+ @version_class.create master_id: master.id, valid_from: Date.parse("2017-01-01"), valid_to: Date.parse("2018-01-01"), price: 0, length: 10
89
+ @version_class.create master_id: master.id, valid_from: Date.parse("2018-01-01"), valid_to: Date.parse("2019-01-01"), price: 0, length: 20
90
+ @version_class.create master_id: master.id, valid_from: Date.parse("2019-01-01"), valid_to: Date.parse("2020-01-01"), price: 10, length: 20
91
+ expect(
92
+ master.update_attributes valid_from: Date.parse("2016-01-01"), price: 10
93
+ ).to be_truthy
94
+ result = master.versions_dataset.all.map do |version|
95
+ [!!version.expired_at, version.valid_from.year, version.valid_to.year, version.price, version.length, version.width, version[:name]]
96
+ end
97
+ expect(result).to match_array [
98
+ [false, 2016, 2017, 10, nil, nil, nil],
99
+ [false, 2017, 2018, 0, 10, nil, "{}"],
100
+ [false, 2018, 2019, 0, 20, nil, nil],
101
+ [false, 2019, 2020, 10, 20, nil, nil],
102
+ [true, 2016, 2017, 0, nil, nil, nil],
103
+ [true, 2017, 2018, 0, 10, nil, nil],
104
+ ]
105
+ ensure
106
+ @version_class.class_eval do
107
+ undef_method :name
108
+ end
109
+ @master_class.instance_variable_set :@propagate_per_column, propagate_per_column
110
+ end
111
+ end
112
+
75
113
  end
data/spec/spec_helper.rb CHANGED
@@ -12,11 +12,7 @@ rspec_exclusions = {}
12
12
  DB = if DbHelpers.pg?
13
13
  `createdb sequel_bitemporal_test`
14
14
  Sequel.extension :pg_range, :pg_range_ops
15
- if ::Sequel::Plugins::Bitemporal.jruby?
16
- Sequel.connect "jdbc:postgresql://localhost/sequel_bitemporal_test"
17
- else
18
- Sequel.postgres "sequel_bitemporal_test"
19
- end
15
+ Sequel.connect DbHelpers.pg_ruby_connect_uri
20
16
  else
21
17
  if Sequel::Plugins::Bitemporal.jruby?
22
18
  rspec_exclusions[:skip_jdbc_sqlite] = true
data/spec/support/db.rb CHANGED
@@ -1,13 +1,26 @@
1
1
  module DbHelpers
2
2
 
3
3
  def self.pg?
4
- ENV.has_key? "PG"
4
+ !ENV.has_key?("TEST_ADAPTER") || ENV["TEST_ADAPTER"]=="postgresql"
5
5
  end
6
6
 
7
7
  def self.jruby?
8
8
  (defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby') || defined?(JRUBY_VERSION)
9
9
  end
10
10
 
11
+ def self.pg_ruby_connect_uri
12
+ username = ENV.fetch("TEST_USERNAME", nil)
13
+ password = ENV.fetch("TEST_PASSWORD", nil)
14
+ auth = [username, password].compact.join(":")
15
+
16
+ uri = "postgresql://#{"#{auth}@" unless auth.empty?}#{ENV.fetch("TEST_DATABASE_HOST", "127.0.0.1")}:#{ENV.fetch("TEST_DATABASE_PORT", "5432")}/#{ENV.fetch("TEST_DATABASE", "sequel_bitemporal_test")}"
17
+ if jruby?
18
+ "jdbc:#{uri}"
19
+ else
20
+ uri
21
+ end
22
+ end
23
+
11
24
  def db_setup(opts={})
12
25
  use_time = opts[:use_time]
13
26
  DB.drop_table(:room_versions) if DB.table_exists?(:room_versions)
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel_bitemporal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joseph HALTER
8
8
  - Jonathan TRON
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-01-29 00:00:00.000000000 Z
12
+ date: 2024-02-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sequel
@@ -81,10 +81,10 @@ executables: []
81
81
  extensions: []
82
82
  extra_rdoc_files: []
83
83
  files:
84
+ - ".github/workflows/ci.yml"
84
85
  - ".gitignore"
85
86
  - ".rspec"
86
87
  - ".ruby-version"
87
- - ".travis.yml"
88
88
  - Gemfile
89
89
  - LICENSE
90
90
  - README.md
@@ -106,7 +106,7 @@ homepage: https://github.com/TalentBox/sequel_bitemporal
106
106
  licenses:
107
107
  - MIT
108
108
  metadata: {}
109
- post_install_message:
109
+ post_install_message:
110
110
  rdoc_options: []
111
111
  require_paths:
112
112
  - lib
@@ -121,9 +121,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
121
  - !ruby/object:Gem::Version
122
122
  version: '0'
123
123
  requirements: []
124
- rubyforge_project:
125
- rubygems_version: 2.7.6
126
- signing_key:
124
+ rubygems_version: 3.5.3
125
+ signing_key:
127
126
  specification_version: 4
128
127
  summary: Bitemporal versioning for sequel.
129
128
  test_files:
data/.travis.yml DELETED
@@ -1,24 +0,0 @@
1
- language: ruby
2
- cache:
3
- bundler: true
4
- sudo: false
5
- rvm:
6
- - 2.2.7
7
- - 2.3.4
8
- - 2.4.2
9
- - jruby-9.1.13.0
10
- before_script:
11
- - psql -c 'create database sequel_bitemporal_test;' -U postgres
12
- env:
13
- - SQLITE=1 SEQUEL='~> 4.0'
14
- - SQLITE=1 SEQUEL='~> 5.0'
15
- - PG=1 SEQUEL='~> 4.0'
16
- - PG=1 SEQUEL='~> 5.0'
17
- gemfile:
18
- - ci/sequel.gemfile
19
- matrix:
20
- allow_failures:
21
- - rvm: jruby-9.1.13.0
22
- env: PG=1 SEQUEL='~> 4.0'
23
- - rvm: jruby-9.1.13.0
24
- env: PG=1 SEQUEL='~> 5.0'