rails_event_store_active_record 2.6.0 → 2.8.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: 1445359a7bc2b8138812009c8d556e9a6deae03871ac6e7119f2bd987d67f993
4
- data.tar.gz: 8252c208d67c7ede155d5b26590bff5bc66435b238412f8e64451f331050f4dc
3
+ metadata.gz: fd05a165bf6e5f4b077c79cbb48f24533daf854acd024a6bb5bffec8c1698856
4
+ data.tar.gz: b0acdb12c48a3dc1c04952cf076bb76846bca9c889dd483098d8982cbdc347f3
5
5
  SHA512:
6
- metadata.gz: 8e5f036edb8a06087486c6daf13ddb8ce9ebfd80faffd49ee00aeae030438f6c40082f094bed22ba6b03c4a1a9369e236703b0e7406dfe1b8b841ae72a712b11
7
- data.tar.gz: 403c082973e88aa2a2dc87fe5ea1c2c1b4e9f8c6b622352f79d0fa80d3c7e3ff280f4d5ea9579cf31fec41a5d79b4540048a989a4a114c0e66ec51e4ec7f4262
6
+ metadata.gz: d1e4460ec40756d126b685d6809f12538d5dfee910ee7fbb2f755276607d536cb4d1d58988cbe75903adebe985c258a73d3bce3dc9a68091313a898addb08570
7
+ data.tar.gz: b464d389f5b7af91647da038c2e4916e0c3c78345d4bd7dcac4ff61299733cc7418ae5394363bcadfbc16f5a6504fd09250b818253311767bad7071b3de74328
@@ -1,12 +1,3 @@
1
- # frozen_string_literal: true
1
+ require "ruby_event_store/active_record"
2
2
 
3
- require_relative "rails_event_store_active_record/generators/migration_generator"
4
- require_relative "rails_event_store_active_record/event"
5
- require_relative "rails_event_store_active_record/with_default_models"
6
- require_relative "rails_event_store_active_record/with_abstract_base_class"
7
- require_relative "rails_event_store_active_record/event_repository"
8
- require_relative "rails_event_store_active_record/batch_enumerator"
9
- require_relative "rails_event_store_active_record/event_repository_reader"
10
- require_relative "rails_event_store_active_record/index_violation_detector"
11
- require_relative "rails_event_store_active_record/pg_linearized_event_repository"
12
- require_relative "rails_event_store_active_record/version"
3
+ RailsEventStoreActiveRecord = RubyEventStore::ActiveRecord
metadata CHANGED
@@ -1,43 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_event_store_active_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.0
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arkency
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-29 00:00:00.000000000 Z
11
+ date: 2023-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: ruby_event_store
14
+ name: ruby_event_store-active_record
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 2.6.0
19
+ version: 2.8.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 2.6.0
27
- - !ruby/object:Gem::Dependency
28
- name: activerecord
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '6.0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '6.0'
26
+ version: 2.8.0
41
27
  description: |
42
28
  Persistent event repository implementation for RubyEventStore based on ActiveRecord. Ships with database schema
43
29
  and migrations suitable for PostgreSQL, MySQL ans SQLite database engines.
@@ -47,22 +33,9 @@ description: |
47
33
  email: dev@arkency.com
48
34
  executables: []
49
35
  extensions: []
50
- extra_rdoc_files:
51
- - README.md
36
+ extra_rdoc_files: []
52
37
  files:
53
- - README.md
54
38
  - lib/rails_event_store_active_record.rb
55
- - lib/rails_event_store_active_record/batch_enumerator.rb
56
- - lib/rails_event_store_active_record/event.rb
57
- - lib/rails_event_store_active_record/event_repository.rb
58
- - lib/rails_event_store_active_record/event_repository_reader.rb
59
- - lib/rails_event_store_active_record/generators/migration_generator.rb
60
- - lib/rails_event_store_active_record/generators/templates/create_event_store_events_template.rb
61
- - lib/rails_event_store_active_record/index_violation_detector.rb
62
- - lib/rails_event_store_active_record/pg_linearized_event_repository.rb
63
- - lib/rails_event_store_active_record/version.rb
64
- - lib/rails_event_store_active_record/with_abstract_base_class.rb
65
- - lib/rails_event_store_active_record/with_default_models.rb
66
39
  homepage: https://railseventstore.org
67
40
  licenses:
68
41
  - MIT
@@ -87,7 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
60
  - !ruby/object:Gem::Version
88
61
  version: '0'
89
62
  requirements: []
90
- rubygems_version: 3.3.26
63
+ rubygems_version: 3.3.7
91
64
  signing_key:
92
65
  specification_version: 4
93
66
  summary: Persistent event repository implementation for RubyEventStore based on ActiveRecord
data/README.md DELETED
@@ -1,7 +0,0 @@
1
- # RailsEventStoreActiveRecord
2
-
3
- Persistent event repository implementation for RubyEventStore based on ActiveRecord. Ships with database schema and migrations suitable for PostgreSQL, MySQL ans SQLite database engines.
4
-
5
- Includes repository implementation with linearized writes to achieve log-like properties of streams on top of SQL database engine.
6
-
7
- Find out more at [https://railseventstore.org](https://railseventstore.org/)
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsEventStoreActiveRecord
4
- class BatchEnumerator
5
- def initialize(batch_size, total_limit, reader)
6
- @batch_size = batch_size
7
- @total_limit = total_limit
8
- @reader = reader
9
- end
10
-
11
- def each
12
- return to_enum unless block_given?
13
- offset_id = nil
14
-
15
- 0.step(total_limit - 1, batch_size) do |batch_offset|
16
- batch_limit = [batch_size, total_limit - batch_offset].min
17
- results, offset_id = reader.call(offset_id, batch_limit)
18
-
19
- break if results.empty?
20
- yield results
21
- end
22
- end
23
-
24
- def first
25
- each.first
26
- end
27
-
28
- def to_a
29
- each.to_a
30
- end
31
-
32
- private
33
-
34
- attr_reader :batch_size, :total_limit, :reader
35
- end
36
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "active_record"
4
-
5
- module RailsEventStoreActiveRecord
6
- class Event < ::ActiveRecord::Base
7
- self.primary_key = :id
8
- self.table_name = "event_store_events"
9
- end
10
- private_constant :Event
11
-
12
- class EventInStream < ::ActiveRecord::Base
13
- self.primary_key = :id
14
- self.table_name = "event_store_events_in_streams"
15
- belongs_to :event, primary_key: :event_id
16
- end
17
- private_constant :EventInStream
18
- end
@@ -1,162 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "active_support/core_ext/array"
4
-
5
- module RailsEventStoreActiveRecord
6
- class EventRepository
7
- POSITION_SHIFT = 1
8
-
9
- def initialize(model_factory: WithDefaultModels.new, serializer:)
10
- @serializer = serializer
11
-
12
- @event_klass, @stream_klass = model_factory.call
13
- @repo_reader = EventRepositoryReader.new(@event_klass, @stream_klass, serializer)
14
- @index_violation_detector = IndexViolationDetector.new(@event_klass.table_name, @stream_klass.table_name)
15
- end
16
-
17
- def append_to_stream(records, stream, expected_version)
18
- return if records.empty?
19
-
20
- hashes = []
21
- event_ids = []
22
- records.each do |record|
23
- hashes << insert_hash(record, record.serialize(serializer))
24
- event_ids << record.event_id
25
- end
26
- add_to_stream(event_ids, stream, expected_version) { @event_klass.insert_all!(hashes) }
27
- end
28
-
29
- def link_to_stream(event_ids, stream, expected_version)
30
- return if event_ids.empty?
31
-
32
- (event_ids - @event_klass.where(event_id: event_ids).pluck(:event_id)).each do |id|
33
- raise RubyEventStore::EventNotFound.new(id)
34
- end
35
- add_to_stream(event_ids, stream, expected_version)
36
- end
37
-
38
- def delete_stream(stream)
39
- @stream_klass.where(stream: stream.name).delete_all
40
- end
41
-
42
- def has_event?(event_id)
43
- @repo_reader.has_event?(event_id)
44
- end
45
-
46
- def last_stream_event(stream)
47
- @repo_reader.last_stream_event(stream)
48
- end
49
-
50
- def read(specification)
51
- @repo_reader.read(specification)
52
- end
53
-
54
- def count(specification)
55
- @repo_reader.count(specification)
56
- end
57
-
58
- def update_messages(records)
59
- hashes = records.map { |record| upsert_hash(record, record.serialize(serializer)) }
60
- for_update = records.map(&:event_id)
61
- start_transaction do
62
- existing =
63
- @event_klass
64
- .where(event_id: for_update)
65
- .pluck(:event_id, :id, :created_at)
66
- .reduce({}) { |acc, (event_id, id, created_at)| acc.merge(event_id => [id, created_at]) }
67
- (for_update - existing.keys).each { |id| raise RubyEventStore::EventNotFound.new(id) }
68
- hashes.each do |h|
69
- h[:id] = existing.fetch(h.fetch(:event_id)).at(0)
70
- h[:created_at] = existing.fetch(h.fetch(:event_id)).at(1)
71
- end
72
- @event_klass.upsert_all(hashes)
73
- end
74
- end
75
-
76
- def streams_of(event_id)
77
- @repo_reader.streams_of(event_id)
78
- end
79
-
80
- def position_in_stream(event_id, stream)
81
- @repo_reader.position_in_stream(event_id, stream)
82
- end
83
-
84
- def global_position(event_id)
85
- @repo_reader.global_position(event_id)
86
- end
87
-
88
- def event_in_stream?(event_id, stream)
89
- @repo_reader.event_in_stream?(event_id, stream)
90
- end
91
-
92
- private
93
-
94
- attr_reader :serializer
95
-
96
- def add_to_stream(event_ids, stream, expected_version)
97
- last_stream_version = ->(stream_) do
98
- @stream_klass.where(stream: stream_.name).order("position DESC").first.try(:position)
99
- end
100
- resolved_version = expected_version.resolve_for(stream, last_stream_version)
101
-
102
- start_transaction do
103
- yield if block_given?
104
- in_stream =
105
- event_ids.map.with_index do |event_id, index|
106
- {
107
- stream: stream.name,
108
- position: compute_position(resolved_version, index),
109
- event_id: event_id,
110
- created_at: Time.now.utc
111
- }
112
- end
113
- @stream_klass.insert_all!(in_stream) unless stream.global?
114
- end
115
- self
116
- rescue ActiveRecord::RecordNotUnique => e
117
- raise_error(e)
118
- end
119
-
120
- def raise_error(e)
121
- raise RubyEventStore::EventDuplicatedInStream if detect_index_violated(e.message)
122
- raise RubyEventStore::WrongExpectedEventVersion
123
- end
124
-
125
- def compute_position(resolved_version, index)
126
- resolved_version + index + POSITION_SHIFT unless resolved_version.nil?
127
- end
128
-
129
- def detect_index_violated(message)
130
- @index_violation_detector.detect(message)
131
- end
132
-
133
- def insert_hash(record, serialized_record)
134
- {
135
- event_id: serialized_record.event_id,
136
- data: serialized_record.data,
137
- metadata: serialized_record.metadata,
138
- event_type: serialized_record.event_type,
139
- created_at: record.timestamp,
140
- valid_at: optimize_timestamp(record.valid_at, record.timestamp)
141
- }
142
- end
143
-
144
- def upsert_hash(record, serialized_record)
145
- {
146
- event_id: serialized_record.event_id,
147
- data: serialized_record.data,
148
- metadata: serialized_record.metadata,
149
- event_type: serialized_record.event_type,
150
- valid_at: optimize_timestamp(record.valid_at, record.timestamp)
151
- }
152
- end
153
-
154
- def optimize_timestamp(valid_at, created_at)
155
- valid_at unless valid_at.eql?(created_at)
156
- end
157
-
158
- def start_transaction(&block)
159
- @event_klass.transaction(requires_new: true, &block)
160
- end
161
- end
162
- end
@@ -1,199 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsEventStoreActiveRecord
4
- class EventRepositoryReader
5
- def initialize(event_klass, stream_klass, serializer)
6
- @event_klass = event_klass
7
- @stream_klass = stream_klass
8
- @serializer = serializer
9
- end
10
-
11
- def has_event?(event_id)
12
- @event_klass.exists?(event_id: event_id)
13
- end
14
-
15
- def last_stream_event(stream)
16
- record_ = @stream_klass.where(stream: stream.name).order("position DESC, id DESC").first
17
- record(record_) if record_
18
- end
19
-
20
- def read(spec)
21
- stream = read_scope(spec)
22
- if spec.batched?
23
- spec.time_sort_by ? offset_limit_batch_reader(spec, stream) : monotonic_id_batch_reader(spec, stream)
24
- elsif spec.first?
25
- record_ = stream.first
26
- record(record_) if record_
27
- elsif spec.last?
28
- record_ = stream.last
29
- record(record_) if record_
30
- else
31
- stream.map(&method(:record)).each
32
- end
33
- end
34
-
35
- def count(spec)
36
- read_scope(spec).count
37
- end
38
-
39
- def streams_of(event_id)
40
- @stream_klass.where(event_id: event_id).pluck(:stream).map { |name| RubyEventStore::Stream.new(name) }
41
- end
42
-
43
- def position_in_stream(event_id, stream)
44
- record = @stream_klass.select("position").where(stream: stream.name).find_by(event_id: event_id)
45
- raise RubyEventStore::EventNotFoundInStream if record.nil?
46
- record.position
47
- end
48
-
49
- def global_position(event_id)
50
- record = @event_klass.select("id").find_by(event_id: event_id)
51
- raise RubyEventStore::EventNotFound.new(event_id) if record.nil?
52
- record.id - 1
53
- end
54
-
55
- def event_in_stream?(event_id, stream)
56
- @stream_klass.where(event_id: event_id, stream: stream.name).exists?
57
- end
58
-
59
- private
60
-
61
- attr_reader :serializer
62
-
63
- def offset_limit_batch_reader(spec, stream)
64
- batch_reader = ->(offset, limit) { stream.offset(offset).limit(limit).map(&method(:record)) }
65
- RubyEventStore::BatchEnumerator.new(spec.batch_size, spec.limit, batch_reader).each
66
- end
67
-
68
- def monotonic_id_batch_reader(spec, stream)
69
- batch_reader = ->(offset_id, limit) do
70
- search_in = spec.stream.global? ? @event_klass.table_name : @stream_klass.table_name
71
- records =
72
- if offset_id.nil?
73
- stream.limit(limit)
74
- else
75
- stream.where(start_offset_condition(spec, offset_id, search_in)).limit(limit)
76
- end
77
- [records.map(&method(:record)), records.last]
78
- end
79
- BatchEnumerator.new(spec.batch_size, spec.limit, batch_reader).each
80
- end
81
-
82
- def read_scope(spec)
83
- if spec.stream.global?
84
- stream = @event_klass
85
- stream = stream.where(event_id: spec.with_ids) if spec.with_ids?
86
- stream = stream.where(event_type: spec.with_types) if spec.with_types?
87
- stream = ordered(stream, spec)
88
- stream = stream.limit(spec.limit) if spec.limit?
89
- stream = stream.where(start_condition_in_global_stream(spec)) if spec.start
90
- stream = stream.where(stop_condition_in_global_stream(spec)) if spec.stop
91
- stream = stream.where(older_than_condition(spec)) if spec.older_than
92
- stream = stream.where(older_than_or_equal_condition(spec)) if spec.older_than_or_equal
93
- stream = stream.where(newer_than_condition(spec)) if spec.newer_than
94
- stream = stream.where(newer_than_or_equal_condition(spec)) if spec.newer_than_or_equal
95
- stream.order(id: order(spec))
96
- else
97
- stream = @stream_klass.preload(:event).where(stream: spec.stream.name)
98
- stream = stream.where(event_id: spec.with_ids) if spec.with_ids?
99
- stream = stream.where(@event_klass.table_name => { event_type: spec.with_types }) if spec.with_types?
100
- stream = ordered(stream.joins(:event), spec)
101
- stream = stream.order(id: order(spec))
102
- stream = stream.limit(spec.limit) if spec.limit?
103
- stream = stream.where(start_condition(spec)) if spec.start
104
- stream = stream.where(stop_condition(spec)) if spec.stop
105
- stream = stream.where(older_than_condition(spec)) if spec.older_than
106
- stream = stream.where(older_than_or_equal_condition(spec)) if spec.older_than_or_equal
107
- stream = stream.where(newer_than_condition(spec)) if spec.newer_than
108
- stream = stream.where(newer_than_or_equal_condition(spec)) if spec.newer_than_or_equal
109
- stream
110
- end
111
- end
112
-
113
- def ordered(stream, spec)
114
- case spec.time_sort_by
115
- when :as_at
116
- stream.order("#{@event_klass.table_name}.created_at #{order(spec)}")
117
- when :as_of
118
- stream.order("#{@event_klass.table_name}.valid_at #{order(spec)}")
119
- else
120
- stream
121
- end
122
- end
123
-
124
- def start_offset_condition(specification, record_id, search_in)
125
- condition = "#{search_in}.id #{specification.forward? ? ">" : "<"} ?"
126
- [condition, record_id]
127
- end
128
-
129
- def stop_offset_condition(specification, record_id, search_in)
130
- condition = "#{search_in}.id #{specification.forward? ? "<" : ">"} ?"
131
- [condition, record_id]
132
- end
133
-
134
- def start_condition(specification)
135
- start_offset_condition(
136
- specification,
137
- @stream_klass.find_by!(event_id: specification.start, stream: specification.stream.name),
138
- @stream_klass.table_name
139
- )
140
- end
141
-
142
- def stop_condition(specification)
143
- stop_offset_condition(
144
- specification,
145
- @stream_klass.find_by!(event_id: specification.stop, stream: specification.stream.name),
146
- @stream_klass.table_name
147
- )
148
- end
149
-
150
- def start_condition_in_global_stream(specification)
151
- start_offset_condition(
152
- specification,
153
- @event_klass.find_by!(event_id: specification.start),
154
- @event_klass.table_name
155
- )
156
- end
157
-
158
- def stop_condition_in_global_stream(specification)
159
- stop_offset_condition(specification, @event_klass.find_by!(event_id: specification.stop), @event_klass.table_name)
160
- end
161
-
162
- def older_than_condition(specification)
163
- ["#{@event_klass.table_name}.created_at < ?", specification.older_than]
164
- end
165
-
166
- def older_than_or_equal_condition(specification)
167
- ["#{@event_klass.table_name}.created_at <= ?", specification.older_than_or_equal]
168
- end
169
-
170
- def newer_than_condition(specification)
171
- ["#{@event_klass.table_name}.created_at > ?", specification.newer_than]
172
- end
173
-
174
- def newer_than_or_equal_condition(specification)
175
- ["#{@event_klass.table_name}.created_at >= ?", specification.newer_than_or_equal]
176
- end
177
-
178
- def order(spec)
179
- spec.forward? ? "ASC" : "DESC"
180
- end
181
-
182
- def record(record)
183
- record = record.event if @stream_klass === record
184
-
185
- RubyEventStore::SerializedRecord
186
- .new(
187
- event_id: record.event_id,
188
- metadata: record.metadata,
189
- data: record.data,
190
- event_type: record.event_type,
191
- timestamp: record.created_at.iso8601(RubyEventStore::TIMESTAMP_PRECISION),
192
- valid_at: (record.valid_at || record.created_at).iso8601(RubyEventStore::TIMESTAMP_PRECISION)
193
- )
194
- .deserialize(serializer)
195
- end
196
- end
197
-
198
- private_constant(:EventRepositoryReader)
199
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- begin
4
- require "rails/generators"
5
- rescue LoadError
6
- end
7
-
8
- module RailsEventStoreActiveRecord
9
- class MigrationGenerator < Rails::Generators::Base
10
- class Error < Thor::Error
11
- end
12
-
13
- DATA_TYPES = %w[binary json jsonb].freeze
14
-
15
- source_root File.expand_path(File.join(File.dirname(__FILE__), "../generators/templates"))
16
- class_option(
17
- :data_type,
18
- type: :string,
19
- default: "binary",
20
- desc:
21
- "Configure the data type for `data` and `meta data` fields in Postgres migration (options: #{DATA_TYPES.join("/")})"
22
- )
23
-
24
- def initialize(*args)
25
- super
26
-
27
- if DATA_TYPES.exclude?(options.fetch(:data_type))
28
- raise Error, "Invalid value for --data-type option. Supported for options are: #{DATA_TYPES.join(", ")}."
29
- end
30
- end
31
-
32
- def create_migration
33
- template "create_event_store_events_template.rb", "db/migrate/#{timestamp}_create_event_store_events.rb"
34
- end
35
-
36
- private
37
-
38
- def data_type
39
- options.fetch("data_type")
40
- end
41
-
42
- def migration_version
43
- "[4.2]"
44
- end
45
-
46
- def timestamp
47
- Time.now.strftime("%Y%m%d%H%M%S")
48
- end
49
- end
50
- end if defined?(Rails::Generators::Base)
@@ -1,55 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class CreateEventStoreEvents < ActiveRecord::Migration<%= migration_version %>
4
- def change
5
- postgres =
6
- ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
7
- if postgres
8
- create_table(:event_store_events_in_streams, id: :bigserial, force: false) do |t|
9
- t.string :stream, null: false
10
- t.integer :position, null: true
11
- t.references :event, null: false, type: :uuid
12
- t.datetime :created_at, null: false
13
- end
14
- add_index :event_store_events_in_streams, [:stream, :position], unique: true
15
- add_index :event_store_events_in_streams, [:created_at]
16
- add_index :event_store_events_in_streams, [:stream, :event_id], unique: true
17
-
18
- create_table(:event_store_events, id: :bigserial, force: false) do |t|
19
- t.references :event, null: false, type: :uuid
20
- t.string :event_type, null: false
21
- t.<%= data_type %> :metadata
22
- t.<%= data_type %> :data, null: false
23
- t.datetime :created_at, null: false
24
- t.datetime :valid_at, null: true
25
- end
26
- add_index :event_store_events, :event_id, unique: true
27
- add_index :event_store_events, :created_at
28
- add_index :event_store_events, :valid_at
29
- add_index :event_store_events, :event_type
30
- else
31
- create_table(:event_store_events_in_streams, force: false) do |t|
32
- t.string :stream, null: false
33
- t.integer :position, null: true
34
- t.references :event, null: false, type: :string, limit: 36
35
- t.datetime :created_at, null: false, precision: 6
36
- end
37
- add_index :event_store_events_in_streams, [:stream, :position], unique: true
38
- add_index :event_store_events_in_streams, [:created_at]
39
- add_index :event_store_events_in_streams, [:stream, :event_id], unique: true
40
-
41
- create_table(:event_store_events, force: false) do |t|
42
- t.references :event, null: false, type: :string, limit: 36
43
- t.string :event_type, null: false
44
- t.binary :metadata
45
- t.binary :data, null: false
46
- t.datetime :created_at, null: false, precision: 6
47
- t.datetime :valid_at, null: true, precision: 6
48
- end
49
- add_index :event_store_events, :event_id, unique: true
50
- add_index :event_store_events, :created_at
51
- add_index :event_store_events, :valid_at
52
- add_index :event_store_events, :event_type
53
- end
54
- end
55
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsEventStoreActiveRecord
4
- class IndexViolationDetector
5
- def initialize(event_store_events, event_store_events_in_streams)
6
- @postgres_pkey_error = "Key (event_id)".freeze
7
- @postgres_index_error = "Key (stream, event_id)".freeze
8
- @mysql5_pkey_error = "for key 'index_#{event_store_events}_on_event_id'".freeze
9
- @mysql8_pkey_error = "for key '#{event_store_events}.index_#{event_store_events}_on_event_id'".freeze
10
- @mysql5_index_error = "for key 'index_#{event_store_events_in_streams}_on_stream_and_event_id'".freeze
11
- @mysql8_index_error =
12
- "for key '#{event_store_events_in_streams}.index_#{event_store_events_in_streams}_on_stream_and_event_id'"
13
- .freeze
14
- @sqlite3_pkey_error = "constraint failed: #{event_store_events}.event_id".freeze
15
- @sqlite3_index_error =
16
- "constraint failed: #{event_store_events_in_streams}.stream, #{event_store_events_in_streams}.event_id".freeze
17
- end
18
-
19
- def detect(message)
20
- detect_postgres(message) || detect_mysql(message) || detect_sqlite(message)
21
- end
22
-
23
- private
24
-
25
- def detect_postgres(message)
26
- message.include?(@postgres_pkey_error) || message.include?(@postgres_index_error)
27
- end
28
-
29
- def detect_mysql(message)
30
- message.include?(@mysql5_pkey_error) || message.include?(@mysql8_pkey_error) ||
31
- message.include?(@mysql5_index_error) || message.include?(@mysql8_index_error)
32
- end
33
-
34
- def detect_sqlite(message)
35
- message.include?(@sqlite3_pkey_error) || message.include?(@sqlite3_index_error)
36
- end
37
- end
38
-
39
- private_constant(:IndexViolationDetector)
40
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsEventStoreActiveRecord
4
- class PgLinearizedEventRepository < EventRepository
5
- def start_transaction(&proc)
6
- ActiveRecord::Base.transaction(requires_new: true) do
7
- ActiveRecord::Base.connection.execute("SELECT pg_advisory_xact_lock(1845240511599988039) as l").each {}
8
-
9
- proc.call
10
- end
11
- end
12
- end
13
- end
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsEventStoreActiveRecord
4
- VERSION = "2.6.0"
5
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsEventStoreActiveRecord
4
- class WithAbstractBaseClass
5
- def initialize(base_klass)
6
- unless base_klass < ActiveRecord::Base && base_klass.abstract_class?
7
- raise ArgumentError.new("#{base_klass} must be an abstract class that inherits from ActiveRecord::Base")
8
- end
9
- @base_klass = base_klass
10
- end
11
-
12
- def call(instance_id: SecureRandom.hex)
13
- [build_event_klass(instance_id), build_stream_klass(instance_id)]
14
- end
15
-
16
- private
17
-
18
- def build_event_klass(instance_id)
19
- Object.const_set(
20
- "Event_#{instance_id}",
21
- Class.new(@base_klass) do
22
- self.primary_key = :id
23
- self.table_name = "event_store_events"
24
- end
25
- )
26
- end
27
-
28
- def build_stream_klass(instance_id)
29
- Object.const_set(
30
- "EventInStream_#{instance_id}",
31
- Class.new(@base_klass) do
32
- self.primary_key = :id
33
- self.table_name = "event_store_events_in_streams"
34
- belongs_to :event, primary_key: :event_id, class_name: "Event_#{instance_id}"
35
- end
36
- )
37
- end
38
- end
39
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsEventStoreActiveRecord
4
- class WithDefaultModels
5
- def call
6
- [Event, EventInStream]
7
- end
8
- end
9
- end