ruby_event_store-active_record 2.17.1 → 2.18.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: b87772800a0cfa9041b04341fd4b652cb19ed7c651739986f80a7bf0bb17c873
4
- data.tar.gz: 351574e60ba2f36792f689a45fd0bac8503a69bb4622173742147034c58e5d3d
3
+ metadata.gz: 8b1a98f057ae20e009d0e1939e1ae406b99e87584ddd5bfdcb54206ea3224ec6
4
+ data.tar.gz: fb2d8ed0c5fe1016d7bb51e73ebbc67a86306ddfb0c54867d8574bc88186d033
5
5
  SHA512:
6
- metadata.gz: db286b07eac4402fd8a83a143d9501246b6cef625ee2bac0db42dc1a3dc979d48b3526e89ae990cda4202b2ac5187942e2356320fefaf915fec8a0f7c24530f8
7
- data.tar.gz: 3dc022ad1801d62547c91e7b0f7967bbc0a564a147b00d2a67c024bd8859fb00e8c7b3647423db6c5bcc447e2b644727b879f01accc67826e0989f2f0cc84439
6
+ metadata.gz: 99df7fd77ccf209de25cc81b8e81fdafaee33acf0ef329f8cd541e8332f8819632d630cc62afd403c0672ee76ae8159e14fefa1b518639b6e2e5b555b4beb979
7
+ data.tar.gz: 60f305f44dcea39d1408a1776e902f9812b44244b20ee046f115521c34a74864e3e481e53853ab005dbf802cea1570aba9b90bc28afc08b5800cc402ee9df2cc
@@ -7,48 +7,23 @@ module RubyEventStore
7
7
 
8
8
  def initialize(model_factory: WithDefaultModels.new, serializer:)
9
9
  @serializer = serializer
10
- @event_klass, @stream_klass = model_factory.call
11
- if serializer == NULL && json_data_type?
12
- warn <<~MSG
13
- The data or metadata column is of a JSON/B type and expects a JSON string.
14
-
15
- Yet the repository serializer is configured as #{serializer} and it would not
16
- produce the expected JSON string.
17
-
18
- In ActiveRecord there's an implicit serialization to JSON for JSON/B column types
19
- that made it work so far. This behaviour is unfortunately also a source of undesired
20
- double serialization — first in the EventRepository, second in the ActiveRecord.
21
-
22
- In the past we've advised workarounds that introduced configuration incosistency
23
- with other data types and serialization formats, i.e. explicitly passing NULL serializer
24
- just for the JSON/B data types.
25
-
26
- As of now this special ActiveRecord behaviour is disabled. You should be using JSON
27
- serializer back again:
28
-
29
- RubyEventStore::ActiveRecord::EventRepository.new(serializer: JSON)
30
- MSG
31
- else
32
- @event_klass.include(SkipJsonSerialization)
33
- end
34
- @repo_reader = EventRepositoryReader.new(@event_klass, @stream_klass, serializer)
35
- @index_violation_detector = IndexViolationDetector.new(@event_klass.table_name, @stream_klass.table_name)
10
+ @model_factory = model_factory
36
11
  end
37
12
 
38
13
  def rescue_from_double_json_serialization!
39
- if serializer == JSON && json_data_type?
40
- @repo_reader.instance_eval { alias __record__ record }
14
+ if @serializer == JSON && json_data_type?(event_klass)
15
+ repo_reader.instance_eval { alias __record__ record }
41
16
 
42
- @repo_reader.define_singleton_method :unwrap do |column_name, payload|
17
+ repo_reader.define_singleton_method :unwrap do |column_name, payload|
43
18
  if String === payload && payload.start_with?("\{")
44
19
  warn "Double serialization of #{column_name} column detected"
45
- serializer.load(payload)
20
+ @serializer.load(payload)
46
21
  else
47
22
  payload
48
23
  end
49
24
  end
50
25
 
51
- @repo_reader.define_singleton_method :record do |record|
26
+ repo_reader.define_singleton_method :record do |record|
52
27
  r = __record__(record)
53
28
 
54
29
  Record.new(
@@ -76,31 +51,31 @@ module RubyEventStore
76
51
  end
77
52
 
78
53
  def delete_stream(stream)
79
- @stream_klass.where(stream: stream.name).delete_all
54
+ stream_klass.where(stream: stream.name).delete_all
80
55
  end
81
56
 
82
57
  def has_event?(event_id)
83
- @repo_reader.has_event?(event_id)
58
+ repo_reader.has_event?(event_id)
84
59
  end
85
60
 
86
61
  def last_stream_event(stream)
87
- @repo_reader.last_stream_event(stream)
62
+ repo_reader.last_stream_event(stream)
88
63
  end
89
64
 
90
65
  def read(specification)
91
- @repo_reader.read(specification)
66
+ repo_reader.read(specification)
92
67
  end
93
68
 
94
69
  def count(specification)
95
- @repo_reader.count(specification)
70
+ repo_reader.count(specification)
96
71
  end
97
72
 
98
73
  def update_messages(records)
99
- hashes = records.map { |record| upsert_hash(record, record.serialize(serializer)) }
74
+ hashes = records.map { |record| upsert_hash(record, record.serialize(@serializer)) }
100
75
  for_update = records.map(&:event_id)
101
76
  start_transaction do
102
77
  existing =
103
- @event_klass
78
+ event_klass
104
79
  .where(event_id: for_update)
105
80
  .pluck(:event_id, :id, :created_at)
106
81
  .reduce({}) { |acc, (event_id, id, created_at)| acc.merge(event_id => [id, created_at]) }
@@ -109,33 +84,31 @@ module RubyEventStore
109
84
  h[:id] = existing.fetch(h.fetch(:event_id)).at(0)
110
85
  h[:created_at] = existing.fetch(h.fetch(:event_id)).at(1)
111
86
  end
112
- @event_klass.upsert_all(hashes)
87
+ event_klass.upsert_all(hashes)
113
88
  end
114
89
  end
115
90
 
116
91
  def streams_of(event_id)
117
- @repo_reader.streams_of(event_id)
92
+ repo_reader.streams_of(event_id)
118
93
  end
119
94
 
120
95
  def position_in_stream(event_id, stream)
121
- @repo_reader.position_in_stream(event_id, stream)
96
+ repo_reader.position_in_stream(event_id, stream)
122
97
  end
123
98
 
124
99
  def global_position(event_id)
125
- @repo_reader.global_position(event_id)
100
+ repo_reader.global_position(event_id)
126
101
  end
127
102
 
128
103
  def event_in_stream?(event_id, stream)
129
- @repo_reader.event_in_stream?(event_id, stream)
104
+ repo_reader.event_in_stream?(event_id, stream)
130
105
  end
131
106
 
132
107
  private
133
108
 
134
- attr_reader :serializer
135
-
136
109
  def add_to_stream(event_ids, stream, expected_version)
137
110
  last_stream_version = ->(stream_) do
138
- @stream_klass.where(stream: stream_.name).order("position DESC").first.try(:position)
111
+ stream_klass.where(stream: stream_.name).order("position DESC").first.try(:position)
139
112
  end
140
113
  resolved_version = expected_version.resolve_for(stream, last_stream_version)
141
114
 
@@ -150,7 +123,7 @@ module RubyEventStore
150
123
  created_at: Time.now.utc,
151
124
  }
152
125
  end
153
- @stream_klass.insert_all!(in_stream) unless stream.global?
126
+ stream_klass.insert_all!(in_stream) unless stream.global?
154
127
  end
155
128
  self
156
129
  rescue ::ActiveRecord::RecordNotUnique => e
@@ -167,7 +140,7 @@ module RubyEventStore
167
140
  end
168
141
 
169
142
  def detect_index_violated(message)
170
- @index_violation_detector.detect(message)
143
+ index_violation_detector.detect(message)
171
144
  end
172
145
 
173
146
  def insert_hash(record, serialized_record)
@@ -196,11 +169,11 @@ module RubyEventStore
196
169
  end
197
170
 
198
171
  def start_transaction(&block)
199
- @event_klass.transaction(requires_new: true, &block)
172
+ event_klass.transaction(requires_new: true, &block)
200
173
  end
201
174
 
202
175
  def link_to_stream_(event_ids, stream, expected_version)
203
- (event_ids - @event_klass.where(event_id: event_ids).pluck(:event_id)).each { |id| raise EventNotFound.new(id) }
176
+ (event_ids - event_klass.where(event_id: event_ids).pluck(:event_id)).each { |id| raise EventNotFound.new(id) }
204
177
  add_to_stream(event_ids, stream, expected_version)
205
178
  end
206
179
 
@@ -208,16 +181,53 @@ module RubyEventStore
208
181
  hashes = []
209
182
  event_ids = []
210
183
  records.each do |record|
211
- hashes << insert_hash(record, record.serialize(serializer))
184
+ hashes << insert_hash(record, record.serialize(@serializer))
212
185
  event_ids << record.event_id
213
186
  end
214
- add_to_stream(event_ids, stream, expected_version) { @event_klass.insert_all!(hashes) }
187
+ add_to_stream(event_ids, stream, expected_version) { event_klass.insert_all!(hashes) }
215
188
  end
216
189
 
217
- private
190
+ def model_klasses
191
+ @model_klasses ||= @model_factory.call.tap do |event_model, stream_model|
192
+ if @serializer == NULL && json_data_type?(event_model)
193
+ warn <<~MSG
194
+ The data or metadata column is of a JSON/B type and expects a JSON string.
195
+
196
+ Yet the repository serializer is configured as #{@serializer} and it would not
197
+ produce the expected JSON string.
198
+
199
+ In ActiveRecord there's an implicit serialization to JSON for JSON/B column types
200
+ that made it work so far. This behaviour is unfortunately also a source of undesired
201
+ double serialization — first in the EventRepository, second in the ActiveRecord.
202
+
203
+ In the past we've advised workarounds that introduced configuration incosistency
204
+ with other data types and serialization formats, i.e. explicitly passing NULL serializer
205
+ just for the JSON/B data types.
206
+
207
+ As of now this special ActiveRecord behaviour is disabled. You should be using JSON
208
+ serializer back again:
209
+
210
+ RubyEventStore::ActiveRecord::EventRepository.new(serializer: JSON)
211
+ MSG
212
+ else
213
+ event_model.include(SkipJsonSerialization)
214
+ end
215
+ end
216
+ end
217
+
218
+ def event_klass = model_klasses.first
219
+ def stream_klass = model_klasses.last
220
+
221
+ def repo_reader
222
+ @repo_reader ||= EventRepositoryReader.new(event_klass, stream_klass, @serializer)
223
+ end
224
+
225
+ def index_violation_detector
226
+ @index_violation_detector ||= IndexViolationDetector.new(event_klass.table_name, stream_klass.table_name)
227
+ end
218
228
 
219
- def json_data_type?
220
- %i[data metadata].any? { |attr| @event_klass.column_for_attribute(attr).type.start_with?("json") }
229
+ def json_data_type?(klass)
230
+ %i[data metadata].any? { |attr| klass.column_for_attribute(attr).type.start_with?("json") }
221
231
  end
222
232
  end
223
233
  end
@@ -27,7 +27,7 @@ module RubyEventStore
27
27
 
28
28
  @database_adapter = DatabaseAdapter.from_string(adapter_name, data_type)
29
29
  rescue UnsupportedAdapter => e
30
- raise Error, e.message
30
+ raise Error, e
31
31
  rescue InvalidDataTypeForAdapter
32
32
  raise Error,
33
33
  "Invalid value for --data-type option. Supported for options are: #{DatabaseAdapter.from_string(adapter_name).supported_data_types.join(", ")}."
@@ -3,6 +3,12 @@
3
3
  module RubyEventStore
4
4
  module ActiveRecord
5
5
  class Railtie < ::Rails::Railtie
6
+ initializer "ruby_event_store-active_record" do
7
+ ActiveSupport.on_load(:active_record) do
8
+ require_relative "../active_record/skip_json_serialization"
9
+ require_relative "../active_record/event"
10
+ end
11
+ end
6
12
  end
7
13
  end
8
14
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RubyEventStore
4
4
  module ActiveRecord
5
- VERSION = "2.17.1"
5
+ VERSION = "2.18.0"
6
6
  end
7
7
  end
@@ -15,6 +15,9 @@ require_relative "active_record/event_repository_reader"
15
15
  require_relative "active_record/index_violation_detector"
16
16
  require_relative "active_record/pg_linearized_event_repository"
17
17
  require_relative "active_record/version"
18
- require_relative "active_record/skip_json_serialization"
19
- require_relative "active_record/event"
20
- require_relative "active_record/railtie" if defined?(Rails::Engine)
18
+ if defined?(Rails::Engine)
19
+ require_relative "active_record/railtie"
20
+ else
21
+ require_relative "active_record/skip_json_serialization"
22
+ require_relative "active_record/event"
23
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_event_store-active_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.17.1
4
+ version: 2.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arkency
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 2.17.1
18
+ version: 2.18.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 2.17.1
25
+ version: 2.18.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: activerecord
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -103,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
103
  - !ruby/object:Gem::Version
104
104
  version: '0'
105
105
  requirements: []
106
- rubygems_version: 3.6.9
106
+ rubygems_version: 3.7.2
107
107
  specification_version: 4
108
108
  summary: Persistent event repository implementation for RubyEventStore based on ActiveRecord
109
109
  test_files: []