hoardable 0.18.2 → 0.19.2

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: fa8fcbadc193fbfcbdb4efa5f1030c2ff5a6be1da19b672136ca0ce5a4bfd846
4
- data.tar.gz: 57b7f6fcbe331e181be56a4e8d284bed7ba322c9cb42280917a684e99ae53c0f
3
+ metadata.gz: affe4a55357ac085a712046c50d2742c7f1887947dee2a7e4d221cf5c7fd7086
4
+ data.tar.gz: 7b2112637801d32e5f18a93d3aa54077e631d25fd9ef6a85639770910d87024b
5
5
  SHA512:
6
- metadata.gz: f4adc32f25af165fc80a53b0982b392dc4878ff3b6afcf1f9f892d75acac859c3b8bf1d9a292e9578da25926b349e380e92dd2d06e8bcb683239e0a7b4ddb95e
7
- data.tar.gz: a076911d80e94a764992716188f35dfe5893662e908d40d7f2b7c48305d3188554a494f5c0fd6d598161a16b52abd53a392cf85e29d927535624d25de3ae3b2a
6
+ metadata.gz: dfdf425df919edd8abce1942108881469c3c29b4e3e0ac9641ab56c221a6c0496f73ae7b6c657aa3edf33ae31b265e15d245e1e4d6e41fedbcbc7983af0657f9
7
+ data.tar.gz: 04b2495a301dd95bdd8d7f4af56ea6cf6dac682d7da59e59dee6d40ed031451410344a34f9580551047985009fc17e5ce1ac0e6d83c0a6f531ec071e932788d7
data/CHANGELOG.md CHANGED
@@ -1,3 +1,27 @@
1
+ ## 0.19.2
2
+
3
+ - Consult `inheritance_column` when constructing default scope
4
+
5
+ ## 0.19.1
6
+
7
+ - Thread-safety support added for `with_hoardable_config`.
8
+
9
+ ## 0.19.0
10
+
11
+ - Ensure that stateful Hoardable class methods `with`, `travel_to` and `at` are thread-safe.
12
+
13
+ ## 0.18.2
14
+
15
+ - Fix for using `update_all` with Hoardable records.
16
+
17
+ ## 0.18.1
18
+
19
+ - Support for STI models.
20
+
21
+ ## 0.18.0
22
+
23
+ - Improved compatibilty with using `ActiveRecord` relationship caching when not using `Hoardable.at`.
24
+
1
25
  ## 0.17.0
2
26
 
3
27
  - Much improved performance of setting `hoardable_id` for versions.
data/Gemfile CHANGED
@@ -2,7 +2,12 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "bigdecimal"
5
6
  gem "debug"
7
+ gem "drb"
8
+ gem "logger"
9
+ gem "mutex_m"
10
+ gem "ostruct"
6
11
  if (rails_version = ENV["RAILS_VERSION"])
7
12
  gem "rails", "~> #{rails_version}"
8
13
  else
@@ -46,7 +46,7 @@ module Hoardable
46
46
  hoardable_maybe_add_only(left, collector)
47
47
  else
48
48
  return unless left.instance_variable_get("@klass").in?(Hoardable::REGISTRY)
49
- return if Hoardable.instance_variable_get("@at")
49
+ return if Thread.current[:hoardable_at]
50
50
 
51
51
  collector << "ONLY "
52
52
  end
@@ -28,9 +28,7 @@ module Hoardable
28
28
  end
29
29
 
30
30
  def find_or_initialize_hoardable_event_uuid
31
- Thread.current[:hoardable_event_uuid] ||= (
32
- ActiveRecord::Base.connection.query("SELECT gen_random_uuid();")[0][0]
33
- )
31
+ Thread.current[:hoardable_event_uuid] ||= SecureRandom.uuid
34
32
  end
35
33
 
36
34
  def initialize_version_attributes(operation)
@@ -56,7 +54,7 @@ module Hoardable
56
54
  end
57
55
 
58
56
  def has_one_at_timestamp
59
- Hoardable.instance_variable_get("@at") || source_record.updated_at
57
+ Thread.current[:hoardable_at] || source_record.updated_at
60
58
  rescue NameError
61
59
  raise(UpdatedAtColumnMissingError, source_record.class.table_name)
62
60
  end
@@ -93,7 +91,7 @@ module Hoardable
93
91
  end
94
92
 
95
93
  def initialize_temporal_range
96
- upper_bound = Hoardable.instance_variable_get("@travel_to") || Time.now.utc
94
+ upper_bound = Thread.current[:hoardable_travel_to] || Time.now.utc
97
95
  lower_bound = (previous_temporal_tsrange_end || hoardable_source_epoch)
98
96
 
99
97
  if upper_bound < lower_bound
@@ -6,7 +6,7 @@ module Hoardable
6
6
 
7
7
  # Symbols for use with setting contextual data, when creating versions. See
8
8
  # {file:README.md#tracking-contextual-data README} for more.
9
- DATA_KEYS = %i[meta whodunit event_uuid].freeze
9
+ DATA_KEYS = %i[meta whodunit].freeze
10
10
 
11
11
  # Symbols for use with setting {Hoardable} configuration. See {file:README.md#configuration
12
12
  # README} for more.
@@ -44,13 +44,13 @@ module Hoardable
44
44
 
45
45
  class << self
46
46
  CONFIG_KEYS.each do |key|
47
- define_method(key) { @config[key] }
47
+ define_method(key) { hoardable_config[key] }
48
48
 
49
49
  define_method("#{key}=") { |value| @config[key] = value }
50
50
  end
51
51
 
52
52
  DATA_KEYS.each do |key|
53
- define_method(key) { @context[key] }
53
+ define_method(key) { hoardable_context[key] }
54
54
 
55
55
  define_method("#{key}=") { |value| @context[key] = value }
56
56
  end
@@ -60,14 +60,23 @@ module Hoardable
60
60
  #
61
61
  # @param hash [Hash] config and contextual data to set within a block
62
62
  def with(hash)
63
- current_config = @config
64
- current_context = @context
65
- @config = current_config.merge(hash.slice(*CONFIG_KEYS))
66
- @context = current_context.merge(hash.slice(*DATA_KEYS))
63
+ thread = Thread.current
64
+ current_thread_config = thread[:hoardable_config]
65
+ current_thread_context = thread[:hoardable_context]
66
+ thread[:hoardable_config] = hoardable_config.merge(hash.slice(*CONFIG_KEYS))
67
+ thread[:hoardable_context] = hoardable_context.merge(hash.slice(*DATA_KEYS))
67
68
  yield
68
69
  ensure
69
- @config = current_config
70
- @context = current_context
70
+ thread[:hoardable_config] = current_thread_config
71
+ thread[:hoardable_context] = current_thread_context
72
+ end
73
+
74
+ private def hoardable_config
75
+ @config.merge(Thread.current[:hoardable_config] ||= {})
76
+ end
77
+
78
+ private def hoardable_context
79
+ @context.merge(Thread.current[:hoardable_context] ||= {})
71
80
  end
72
81
 
73
82
  # Allows performing a query for record states at a certain time. Returned {SourceModel}
@@ -75,20 +84,22 @@ module Hoardable
75
84
  #
76
85
  # @param datetime [DateTime, Time] the datetime or time to temporally query records at
77
86
  def at(datetime)
78
- @at = datetime
87
+ thread = Thread.current
88
+ thread[:hoardable_at] = datetime
79
89
  yield
80
90
  ensure
81
- @at = nil
91
+ thread[:hoardable_at] = nil
82
92
  end
83
93
 
84
94
  # Allows calling code to set the upper bound for the temporal range for recorded audits.
85
95
  #
86
96
  # @param datetime [DateTime] the datetime to temporally record versions at
87
97
  def travel_to(datetime)
88
- @travel_to = datetime
98
+ thread = Thread.current
99
+ thread[:hoardable_travel_to] = datetime
89
100
  yield
90
101
  ensure
91
- @travel_to = nil
102
+ thread[:hoardable_travel_to] = nil
92
103
  end
93
104
 
94
105
  # @!visibility private
@@ -13,8 +13,8 @@ module Hoardable
13
13
  end
14
14
 
15
15
  private def hoardable_scope
16
- if Hoardable.instance_variable_get("@at") &&
17
- (hoardable_id = @association.owner.hoardable_id)
16
+ if Thread.current[:hoardable_at]
17
+ (hoardable_id = @association.owner.hoardable_id)
18
18
  @association.scope.rewhere(@association.reflection.foreign_key => hoardable_id)
19
19
  else
20
20
  @association.scope
@@ -36,7 +36,7 @@ module Hoardable
36
36
  # {HasManyExtension} scope is always used when using {Hoardable.at}.
37
37
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
38
38
  def #{args.first}
39
- if Hoardable.instance_variable_get("@at")
39
+ if Thread.current[:hoardable_at]
40
40
  super.extending
41
41
  else
42
42
  super
@@ -9,9 +9,6 @@ module Hoardable
9
9
  extend ActiveSupport::Concern
10
10
 
11
11
  class_methods do
12
- # @!visibility private
13
- attr_reader :_hoardable_config
14
-
15
12
  # If called with a hash, this will set the model-level +Hoardable+ configuration variables. If
16
13
  # called without an argument it will return the computed +Hoardable+ configuration considering
17
14
  # both model-level and global values.
@@ -23,10 +20,7 @@ module Hoardable
23
20
  if hash
24
21
  @_hoardable_config = hash.slice(*CONFIG_KEYS)
25
22
  else
26
- @_hoardable_config ||= {}
27
- CONFIG_KEYS.to_h do |key|
28
- [key, @_hoardable_config.key?(key) ? @_hoardable_config[key] : Hoardable.send(key)]
29
- end
23
+ CONFIG_KEYS.to_h { |key| [key, _hoardable_config.fetch(key) { Hoardable.send(key) }] }
30
24
  end
31
25
  end
32
26
 
@@ -36,11 +30,20 @@ module Hoardable
36
30
  # @param hash [Hash] The +Hoardable+ configuration for the model. Keys must be present in
37
31
  # {CONFIG_KEYS}
38
32
  def with_hoardable_config(hash)
39
- current_config = @_hoardable_config
40
- @_hoardable_config = hash.slice(*CONFIG_KEYS)
33
+ thread = Thread.current
34
+ current_thread_config = thread[hoardable_current_config_key]
35
+ thread[hoardable_current_config_key] = _hoardable_config.merge(hash.slice(*CONFIG_KEYS))
41
36
  yield
42
37
  ensure
43
- @_hoardable_config = current_config
38
+ thread[hoardable_current_config_key] = current_thread_config
39
+ end
40
+
41
+ private def _hoardable_config
42
+ (@_hoardable_config ||= {}).merge(Thread.current[hoardable_current_config_key] ||= {})
43
+ end
44
+
45
+ private def hoardable_current_config_key
46
+ "hoardable_#{name}_config".to_sym
44
47
  end
45
48
  end
46
49
 
@@ -14,15 +14,15 @@ module Hoardable
14
14
  default_scope do
15
15
  scope =
16
16
  (
17
- if (hoardable_at = Hoardable.instance_variable_get("@at"))
17
+ if (hoardable_at = Thread.current[:hoardable_at])
18
18
  at(hoardable_at)
19
19
  else
20
20
  exclude_versions
21
21
  end
22
22
  )
23
- next scope unless klass == version_class && "type".in?(column_names)
23
+ next scope unless klass == version_class && superclass.inheritance_column.in?(column_names)
24
24
 
25
- scope.where(type: superclass.sti_name)
25
+ scope.where(superclass.inheritance_column => superclass.sti_name)
26
26
  end
27
27
 
28
28
  # @!scope class
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hoardable
4
- VERSION = "0.18.2"
4
+ VERSION = "0.19.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hoardable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.2
4
+ version: 0.19.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - justin talbott
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-01-19 00:00:00.000000000 Z
10
+ date: 2025-04-08 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activerecord
@@ -162,7 +161,6 @@ metadata:
162
161
  homepage_uri: https://github.com/waymondo/hoardable
163
162
  source_code_uri: https://github.com/waymondo/hoardable
164
163
  rubygems_mfa_required: 'true'
165
- post_install_message:
166
164
  rdoc_options: []
167
165
  require_paths:
168
166
  - lib
@@ -177,8 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
177
175
  - !ruby/object:Gem::Version
178
176
  version: '0'
179
177
  requirements: []
180
- rubygems_version: 3.5.16
181
- signing_key:
178
+ rubygems_version: 3.6.2
182
179
  specification_version: 4
183
180
  summary: An ActiveRecord extension for versioning and soft-deletion of records in
184
181
  Postgres