sequel_bitemporal 0.9.1 → 0.11.0

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: 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'