ruby_event_store-rom 1.2.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -1
- data/lib/ruby_event_store/rom/changesets/create_events.rb +10 -18
- data/lib/ruby_event_store/rom/changesets/create_stream_entries.rb +6 -11
- data/lib/ruby_event_store/rom/changesets/update_events.rb +32 -19
- data/lib/ruby_event_store/rom/event_repository.rb +53 -51
- data/lib/ruby_event_store/rom/index_violation_detector.rb +29 -0
- data/lib/ruby_event_store/rom/mappers/event_to_serialized_record.rb +4 -4
- data/lib/ruby_event_store/rom/mappers/stream_entry_to_serialized_record.rb +5 -4
- data/lib/ruby_event_store/rom/rake_task.rb +5 -0
- data/lib/ruby_event_store/rom/relations/events.rb +81 -0
- data/lib/ruby_event_store/rom/relations/stream_entries.rb +90 -0
- data/lib/ruby_event_store/rom/repositories/events.rb +43 -29
- data/lib/ruby_event_store/rom/repositories/stream_entries.rb +7 -13
- data/lib/ruby_event_store/rom/{adapters/sql/tasks → tasks}/migration_tasks.rake +9 -9
- data/lib/ruby_event_store/rom/types.rb +2 -2
- data/lib/ruby_event_store/rom/unit_of_work.rb +29 -13
- data/lib/ruby_event_store/rom/version.rb +1 -1
- data/lib/ruby_event_store/rom.rb +29 -102
- data/lib/ruby_event_store-rom.rb +1 -1
- metadata +29 -48
- data/.rubocop.yml +0 -1
- data/.rubocop_todo.yml +0 -84
- data/CHANGELOG.md +0 -9
- data/Gemfile +0 -12
- data/Makefile +0 -57
- data/Rakefile +0 -20
- data/db/migrate/20180327044629_create_ruby_event_store_tables.rb +0 -54
- data/db/migrate/20181026152045_index_by_event_type.rb +0 -9
- data/lib/ruby_event_store/rom/adapters/memory/changesets/create_events.rb +0 -19
- data/lib/ruby_event_store/rom/adapters/memory/changesets/create_stream_entries.rb +0 -19
- data/lib/ruby_event_store/rom/adapters/memory/changesets/update_events.rb +0 -18
- data/lib/ruby_event_store/rom/adapters/memory/relations/events.rb +0 -56
- data/lib/ruby_event_store/rom/adapters/memory/relations/stream_entries.rb +0 -114
- data/lib/ruby_event_store/rom/adapters/memory/unit_of_work.rb +0 -36
- data/lib/ruby_event_store/rom/adapters/sql/changesets/create_events.rb +0 -15
- data/lib/ruby_event_store/rom/adapters/sql/changesets/update_events.rb +0 -41
- data/lib/ruby_event_store/rom/adapters/sql/index_violation_detector.rb +0 -31
- data/lib/ruby_event_store/rom/adapters/sql/rake_task.rb +0 -5
- data/lib/ruby_event_store/rom/adapters/sql/relations/events.rb +0 -27
- data/lib/ruby_event_store/rom/adapters/sql/relations/stream_entries.rb +0 -72
- data/lib/ruby_event_store/rom/memory.rb +0 -82
- data/lib/ruby_event_store/rom/sql.rb +0 -169
- data/lib/ruby_event_store/rom/tuple_uniqueness_error.rb +0 -21
- data/lib/ruby_event_store/spec/rom/event_repository_lint.rb +0 -176
- data/lib/ruby_event_store/spec/rom/relations/events_lint.rb +0 -75
- data/lib/ruby_event_store/spec/rom/relations/stream_entries_lint.rb +0 -198
- data/lib/ruby_event_store/spec/rom/spec_helper_lint.rb +0 -15
- data/lib/ruby_event_store/spec/rom/unit_of_work_lint.rb +0 -37
- data/ruby_event_store-rom.gemspec +0 -37
data/CHANGELOG.md
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
Further changes can be tracked at [releases page](https://github.com/RailsEventStore/rails_event_store/releases).
|
2
|
-
|
3
|
-
### 0.1.0 (03.04.2018)
|
4
|
-
|
5
|
-
* Implemented ROM SQL adapter
|
6
|
-
* Add `rom-sql` 2.4.0 dependency
|
7
|
-
* Add `rom-repository` 2.0.2 dependency
|
8
|
-
* Add `rom-changeset` 1.0.2 dependency
|
9
|
-
* Add `sequel` 4.49 dependency
|
data/Gemfile
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
3
|
-
gemspec
|
4
|
-
|
5
|
-
eval_gemfile File.expand_path('../support/bundler/Gemfile.shared', __dir__)
|
6
|
-
|
7
|
-
gem 'childprocess'
|
8
|
-
gem 'fakefs', '~> 0.11.2'
|
9
|
-
gem 'mysql2', '>= 0.5.3'
|
10
|
-
gem 'pg', '>= 1.2.2'
|
11
|
-
gem 'ruby_event_store', path: '../ruby_event_store'
|
12
|
-
gem 'sqlite3', '1.3.13'
|
data/Makefile
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
GEM_VERSION = $(shell cat ../RES_VERSION)
|
2
|
-
GEM_NAME = ruby_event_store-rom
|
3
|
-
REQUIRE = $(GEM_NAME)
|
4
|
-
IGNORE = RubyEventStore::ROM.setup \
|
5
|
-
RubyEventStore::ROM.setup_defaults \
|
6
|
-
RubyEventStore::ROM.configure \
|
7
|
-
RubyEventStore::ROM.configure_defaults \
|
8
|
-
RubyEventStore::ROM.find_adapters \
|
9
|
-
RubyEventStore::ROM::TupleUniquenessError.for_event_id \
|
10
|
-
RubyEventStore::ROM::TupleUniquenessError.for_stream_and_position \
|
11
|
-
RubyEventStore::ROM::EventRepository\#initialize \
|
12
|
-
RubyEventStore::ROM::EventRepository\#handle_not_found_errors \
|
13
|
-
RubyEventStore::ROM::EventRepository\#handle_unique_violation_errors \
|
14
|
-
RubyEventStore::ROM::EventRepository\#has_event? \
|
15
|
-
RubyEventStore::ROM::EventRepository\#last_stream_event \
|
16
|
-
RubyEventStore::ROM::Repositories::Events\#find_nonexistent_pks \
|
17
|
-
RubyEventStore::ROM::Repositories::StreamEntries\#create_changeset \
|
18
|
-
RubyEventStore::ROM::Changesets::CreateStreamEntries::Defaults.included \
|
19
|
-
RubyEventStore::ROM::Changesets::CreateEvents::Defaults.included \
|
20
|
-
RubyEventStore::ROM::Changesets::UpdateEvents::Defaults.included \
|
21
|
-
RubyEventStore::ROM::Env\#handle_error \
|
22
|
-
RubyEventStore::ROM::Env\#initialize \
|
23
|
-
RubyEventStore::ROM::Env\#register_error_handler \
|
24
|
-
RubyEventStore::ROM::Env\#register_unit_of_work_options \
|
25
|
-
RubyEventStore::ROM::Env\#unit_of_work \
|
26
|
-
RubyEventStore::ROM::UnitOfWork\#call \
|
27
|
-
RubyEventStore::ROM::UnitOfWork\#commit! \
|
28
|
-
RubyEventStore::ROM::SQL::Relations::StreamEntries\#normalize_stream_name \
|
29
|
-
RubyEventStore::ROM::SQL::IndexViolationDetector\#detect \
|
30
|
-
RubyEventStore::ROM::SQL::SpecHelper\#initialize \
|
31
|
-
RubyEventStore::ROM::SQL::SpecHelper\#has_connection_pooling? \
|
32
|
-
RubyEventStore::ROM::SQL::SpecHelper\#close_pool_connection \
|
33
|
-
RubyEventStore::ROM::SQL::SpecHelper\#load_gateway_schema \
|
34
|
-
RubyEventStore::ROM::SQL::SpecHelper\#establish_gateway_connection \
|
35
|
-
RubyEventStore::ROM::SQL::SpecHelper\#drop_gateway_schema \
|
36
|
-
RubyEventStore::ROM::SQL::SpecHelper\#close_gateway_connection \
|
37
|
-
RubyEventStore::ROM::SQL::SpecHelper\#run_lifecycle \
|
38
|
-
RubyEventStore::ROM::SQL::UnitOfWork\#commit! \
|
39
|
-
RubyEventStore::ROM::Memory::SpecHelper\#initialize \
|
40
|
-
RubyEventStore::ROM::Memory::SpecHelper\#close_pool_connection \
|
41
|
-
RubyEventStore::ROM::Memory::SpecHelper\#load_gateway_schema \
|
42
|
-
RubyEventStore::ROM::Memory::SpecHelper\#establish_gateway_connection \
|
43
|
-
RubyEventStore::ROM::Memory::SpecHelper\#drop_gateway_schema \
|
44
|
-
RubyEventStore::ROM::Memory::SpecHelper\#close_gateway_connection \
|
45
|
-
RubyEventStore::ROM::Memory::SpecHelper\#run_lifecycle \
|
46
|
-
RubyEventStore::ROM::Memory::UnitOfWork\#commit! \
|
47
|
-
RubyEventStore::ROM::Memory::Relations::Events\#verify_uniquness! \
|
48
|
-
RubyEventStore::ROM::Memory::Relations::StreamEntries\#verify_uniquness! \
|
49
|
-
RubyEventStore::ROM::Memory::Relations::StreamEntries\#normalize_stream_name
|
50
|
-
SUBJECT ?= RubyEventStore::ROM*
|
51
|
-
DATABASE_URL ?= sqlite::memory:
|
52
|
-
|
53
|
-
include ../support/make/install.mk
|
54
|
-
include ../support/make/test.mk
|
55
|
-
include ../support/make/mutant.mk
|
56
|
-
include ../support/make/gem.mk
|
57
|
-
include ../support/make/help.mk
|
data/Rakefile
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'bundler/gem_tasks'
|
2
|
-
require 'rspec/core/rake_task'
|
3
|
-
require 'ruby_event_store/rom/adapters/sql/rake_task'
|
4
|
-
|
5
|
-
RSpec::Core::RakeTask.new(:spec)
|
6
|
-
task default: [:ci]
|
7
|
-
|
8
|
-
desc 'Run CI tasks'
|
9
|
-
task ci: [:spec]
|
10
|
-
|
11
|
-
begin
|
12
|
-
require 'rubocop/rake_task'
|
13
|
-
|
14
|
-
Rake::Task[:default].enhance [:rubocop]
|
15
|
-
|
16
|
-
RuboCop::RakeTask.new do |task|
|
17
|
-
task.options << '--display-cop-names'
|
18
|
-
end
|
19
|
-
rescue LoadError
|
20
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
require 'rom/sql'
|
2
|
-
|
3
|
-
::ROM::SQL.migration do
|
4
|
-
change do
|
5
|
-
postgres = database_type =~ /postgres/
|
6
|
-
|
7
|
-
# set when copying migrations
|
8
|
-
# or when running tests
|
9
|
-
ENV['DATA_TYPE'] ||= 'text'
|
10
|
-
data_type = ENV['DATA_TYPE'].to_sym
|
11
|
-
data_types = postgres ? %i[text json jsonb] : %i[text]
|
12
|
-
raise ArgumentError, "DATA_TYPE must be: #{data_types.join(', ')}" unless data_types.include?(data_type)
|
13
|
-
|
14
|
-
run 'CREATE EXTENSION IF NOT EXISTS pgcrypto;' if postgres
|
15
|
-
|
16
|
-
create_table? :event_store_events_in_streams do
|
17
|
-
primary_key :id, type: :Bignum, null: false
|
18
|
-
|
19
|
-
column :stream, String, null: false
|
20
|
-
column :position, Integer
|
21
|
-
|
22
|
-
if postgres
|
23
|
-
column :event_id, :uuid, null: false
|
24
|
-
else
|
25
|
-
column :event_id, String, size: 36, null: false
|
26
|
-
end
|
27
|
-
|
28
|
-
column :created_at, DateTime, null: false, index: 'index_event_store_events_in_streams_on_created_at'
|
29
|
-
|
30
|
-
index %i[stream position], unique: true, name: 'index_event_store_events_in_streams_on_stream_and_position'
|
31
|
-
index %i[stream event_id], unique: true, name: 'index_event_store_events_in_streams_on_stream_and_event_id'
|
32
|
-
end
|
33
|
-
|
34
|
-
create_table? :event_store_events do
|
35
|
-
if postgres
|
36
|
-
column :id, :uuid, default: Sequel.function(:gen_random_uuid), primary_key: true
|
37
|
-
else
|
38
|
-
column :id, String, size: 36, null: false, primary_key: true
|
39
|
-
end
|
40
|
-
|
41
|
-
column :event_type, String, null: false
|
42
|
-
|
43
|
-
if data_type =~ /json/
|
44
|
-
column :metadata, data_type
|
45
|
-
column :data, data_type, null: false
|
46
|
-
else
|
47
|
-
column :metadata, String, text: true
|
48
|
-
column :data, String, text: true, null: false
|
49
|
-
end
|
50
|
-
|
51
|
-
column :created_at, DateTime, null: false, index: 'index_event_store_events_on_created_at'
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RubyEventStore
|
4
|
-
module ROM
|
5
|
-
module Memory
|
6
|
-
module Changesets
|
7
|
-
class CreateEvents < ROM::Changesets::CreateEvents
|
8
|
-
def commit
|
9
|
-
relation.by_pk(to_a.map { |e| e[:id] }).each do |tuple|
|
10
|
-
raise TupleUniquenessError.for_event_id(tuple[:id])
|
11
|
-
end
|
12
|
-
|
13
|
-
super
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RubyEventStore
|
4
|
-
module ROM
|
5
|
-
module Memory
|
6
|
-
module Changesets
|
7
|
-
class CreateStreamEntries < ROM::Changesets::CreateStreamEntries
|
8
|
-
def commit
|
9
|
-
to_a.each do |tuple|
|
10
|
-
relation.send(:verify_uniquness!, tuple)
|
11
|
-
end
|
12
|
-
|
13
|
-
super
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RubyEventStore
|
4
|
-
module ROM
|
5
|
-
module Memory
|
6
|
-
module Changesets
|
7
|
-
class UpdateEvents < ROM::Changesets::UpdateEvents
|
8
|
-
def commit
|
9
|
-
to_a.each do |params|
|
10
|
-
attributes = command.input[params].to_h.delete_if { |k, v| k == :created_at && v.nil? }
|
11
|
-
relation.by_pk(params.fetch(:id)).dataset.map { |tuple| tuple.update(attributes) }
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RubyEventStore
|
4
|
-
module ROM
|
5
|
-
module Memory
|
6
|
-
module Relations
|
7
|
-
class Events < ::ROM::Relation[:memory]
|
8
|
-
schema(:events) do
|
9
|
-
attribute :id, ::ROM::Types::Strict::String.meta(primary_key: true)
|
10
|
-
attribute :event_type, ::ROM::Types::Strict::String
|
11
|
-
attribute :metadata, ::ROM::Types::Strict::String.optional
|
12
|
-
attribute :data, ::ROM::Types::Strict::String
|
13
|
-
attribute :created_at, RubyEventStore::ROM::Types::DateTime
|
14
|
-
end
|
15
|
-
|
16
|
-
def create_changeset(tuples)
|
17
|
-
events.changeset(Changesets::CreateEvents, tuples)
|
18
|
-
end
|
19
|
-
|
20
|
-
def update_changeset(tuples)
|
21
|
-
events.changeset(Changesets::UpdateEvents, tuples)
|
22
|
-
end
|
23
|
-
|
24
|
-
def insert(tuple)
|
25
|
-
verify_uniquness!(tuple)
|
26
|
-
super
|
27
|
-
end
|
28
|
-
|
29
|
-
def for_stream_entries(_assoc, stream_entries)
|
30
|
-
restrict(id: stream_entries.map { |e| e[:event_id] })
|
31
|
-
end
|
32
|
-
|
33
|
-
def by_pk(id)
|
34
|
-
restrict(id: id)
|
35
|
-
end
|
36
|
-
|
37
|
-
def exist?
|
38
|
-
one?
|
39
|
-
end
|
40
|
-
|
41
|
-
def pluck(name)
|
42
|
-
map { |e| e[name] }
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def verify_uniquness!(tuple)
|
48
|
-
return unless by_pk(tuple[:id]).exist?
|
49
|
-
|
50
|
-
raise TupleUniquenessError.for_event_id(tuple[:id])
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,114 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RubyEventStore
|
4
|
-
module ROM
|
5
|
-
module Memory
|
6
|
-
module Relations
|
7
|
-
class StreamEntries < ::ROM::Relation[:memory]
|
8
|
-
schema(:stream_entries) do
|
9
|
-
attribute(:id, ::ROM::Types::Strict::Integer.meta(primary_key: true).default { RubyEventStore::ROM::Memory.fetch_next_id })
|
10
|
-
attribute :stream, ::ROM::Types::Strict::String
|
11
|
-
attribute :position, ::ROM::Types::Strict::Integer.optional
|
12
|
-
attribute :event_id, ::ROM::Types::Strict::String.meta(foreign_key: true, relation: :events)
|
13
|
-
attribute :created_at, RubyEventStore::ROM::Types::DateTime
|
14
|
-
|
15
|
-
associations do
|
16
|
-
belongs_to :events, as: :event, foreign_key: :event_id, override: true, view: :for_stream_entries
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def for_events(events)
|
21
|
-
restrict(event_id: events.map { |e| e[:id] })
|
22
|
-
end
|
23
|
-
|
24
|
-
auto_struct true
|
25
|
-
|
26
|
-
SERIALIZED_GLOBAL_STREAM_NAME = 'all'.freeze
|
27
|
-
|
28
|
-
def create_changeset(tuples)
|
29
|
-
changeset(Changesets::CreateStreamEntries, tuples)
|
30
|
-
end
|
31
|
-
|
32
|
-
def offset(num)
|
33
|
-
num.zero? ? self : new(dataset.slice(num..-1) || [])
|
34
|
-
end
|
35
|
-
|
36
|
-
def take(num)
|
37
|
-
num.nil? ? self : super
|
38
|
-
end
|
39
|
-
|
40
|
-
def insert(tuple)
|
41
|
-
verify_uniquness!(tuple)
|
42
|
-
super
|
43
|
-
end
|
44
|
-
|
45
|
-
def delete(tuple)
|
46
|
-
super tuple.to_h
|
47
|
-
end
|
48
|
-
|
49
|
-
def by_stream(stream)
|
50
|
-
restrict(stream: normalize_stream_name(stream))
|
51
|
-
end
|
52
|
-
|
53
|
-
def by_event_id(event_id)
|
54
|
-
restrict(event_id: event_id)
|
55
|
-
end
|
56
|
-
|
57
|
-
def by_event_type(types)
|
58
|
-
for_events(events.restrict(event_type: Array(types)))
|
59
|
-
end
|
60
|
-
|
61
|
-
def by_stream_and_event_id(stream, event_id)
|
62
|
-
restrict(stream: normalize_stream_name(stream), event_id: event_id).one!
|
63
|
-
end
|
64
|
-
|
65
|
-
def max_position(stream)
|
66
|
-
new(by_stream(stream).order(:position).dataset.reverse).project(:position).take(1).one
|
67
|
-
end
|
68
|
-
|
69
|
-
DIRECTION_MAP = {
|
70
|
-
forward: [false, :>, :<],
|
71
|
-
backward: [true, :<, :>]
|
72
|
-
}.freeze
|
73
|
-
|
74
|
-
def ordered(direction, stream, offset_entry_id = nil, stop_entry_id = nil)
|
75
|
-
reverse, operator_offset, operator_stop = DIRECTION_MAP[direction]
|
76
|
-
|
77
|
-
raise ArgumentError, 'Direction must be :forward or :backward' if order.nil?
|
78
|
-
|
79
|
-
order_columns = %i[position id]
|
80
|
-
order_columns.delete(:position) if stream.global?
|
81
|
-
|
82
|
-
query = by_stream(stream)
|
83
|
-
query = query.restrict { |tuple| tuple[:id].public_send(operator_offset, offset_entry_id) } if offset_entry_id
|
84
|
-
query = query.restrict { |tuple| tuple[:id].public_send(operator_stop, stop_entry_id) } if stop_entry_id
|
85
|
-
query = query.order(*order_columns)
|
86
|
-
query = new(query.dataset.reverse) if reverse
|
87
|
-
|
88
|
-
query
|
89
|
-
end
|
90
|
-
|
91
|
-
private
|
92
|
-
|
93
|
-
# Verifies uniqueness of [stream, event_id] and [stream, position]
|
94
|
-
def verify_uniquness!(tuple)
|
95
|
-
stream = tuple[:stream]
|
96
|
-
attrs = %i[position event_id]
|
97
|
-
attrs.delete(:position) if Stream.new(stream).global?
|
98
|
-
|
99
|
-
attrs.each do |key|
|
100
|
-
next if key == :position && tuple[key].nil?
|
101
|
-
next if restrict(:stream => stream, key => tuple.fetch(key)).none?
|
102
|
-
|
103
|
-
raise TupleUniquenessError.public_send(:"for_stream_and_#{key}", stream, tuple.fetch(key))
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
def normalize_stream_name(stream)
|
108
|
-
stream.global? ? SERIALIZED_GLOBAL_STREAM_NAME : stream.name
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RubyEventStore
|
4
|
-
module ROM
|
5
|
-
module Memory
|
6
|
-
class UnitOfWork < ROM::UnitOfWork
|
7
|
-
def self.mutex
|
8
|
-
@mutex ||= Mutex.new
|
9
|
-
end
|
10
|
-
|
11
|
-
def commit!(_gateway, changesets, **_options)
|
12
|
-
self.class.mutex.synchronize do
|
13
|
-
committed = []
|
14
|
-
|
15
|
-
begin
|
16
|
-
until changesets.empty?
|
17
|
-
changeset = changesets.shift
|
18
|
-
relation = env.rom_container.relations[changeset.relation.name]
|
19
|
-
|
20
|
-
committed << [changeset, relation]
|
21
|
-
|
22
|
-
changeset.commit
|
23
|
-
end
|
24
|
-
rescue StandardError
|
25
|
-
committed.reverse_each do |c, r|
|
26
|
-
r.restrict(id: c.to_a.map { |e| e[:id] }).command(:delete, result: :many).call
|
27
|
-
end
|
28
|
-
|
29
|
-
raise
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RubyEventStore
|
4
|
-
module ROM
|
5
|
-
module SQL
|
6
|
-
module Changesets
|
7
|
-
class UpdateEvents < ::ROM::Changeset::Create
|
8
|
-
include ROM::Changesets::UpdateEvents::Defaults
|
9
|
-
|
10
|
-
UPSERT_COLUMNS = %i[event_type data metadata created_at].freeze
|
11
|
-
|
12
|
-
def commit
|
13
|
-
if SQL.supports_on_duplicate_key_update?(relation.dataset.db)
|
14
|
-
commit_on_duplicate_key_update
|
15
|
-
elsif SQL.supports_insert_conflict_update?(relation.dataset.db)
|
16
|
-
commit_insert_conflict_update
|
17
|
-
else
|
18
|
-
raise "Database doesn't support upserts: #{relation.dataset.db.adapter_scheme}"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def commit_on_duplicate_key_update
|
25
|
-
relation.dataset.on_duplicate_key_update(*UPSERT_COLUMNS).multi_insert(to_a)
|
26
|
-
end
|
27
|
-
|
28
|
-
def commit_insert_conflict_update
|
29
|
-
relation.dataset.insert_conflict(
|
30
|
-
# constraint: 'index_name',
|
31
|
-
target: :id,
|
32
|
-
update: UPSERT_COLUMNS.each_with_object({}) do |column, memo|
|
33
|
-
memo[column] = Sequel[:excluded][column]
|
34
|
-
end
|
35
|
-
).multi_insert(to_a)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RubyEventStore
|
4
|
-
module ROM
|
5
|
-
module SQL
|
6
|
-
class IndexViolationDetector
|
7
|
-
MYSQL5_PKEY_ERROR = "for key 'PRIMARY'".freeze
|
8
|
-
MYSQL8_PKEY_ERROR = "for key 'event_store_events.PRIMARY'".freeze
|
9
|
-
POSTGRES_PKEY_ERROR = 'event_store_events_pkey'.freeze
|
10
|
-
SQLITE3_PKEY_ERROR = 'event_store_events.id'.freeze
|
11
|
-
|
12
|
-
MYSQL5_INDEX_ERROR = "for key 'index_event_store_events_in_streams_on_stream_and_event_id'".freeze
|
13
|
-
MYSQL8_INDEX_ERROR = "for key 'event_store_events_in_streams.index_event_store_events_in_streams_on_stream_and_event_id'".freeze
|
14
|
-
POSTGRES_INDEX_ERROR = 'Key (stream, event_id)'.freeze
|
15
|
-
SQLITE3_INDEX_ERROR = 'event_store_events_in_streams.stream, event_store_events_in_streams.event_id'.freeze
|
16
|
-
|
17
|
-
def detect(message)
|
18
|
-
message.include?(MYSQL5_PKEY_ERROR) ||
|
19
|
-
message.include?(MYSQL8_PKEY_ERROR) ||
|
20
|
-
message.include?(POSTGRES_PKEY_ERROR) ||
|
21
|
-
message.include?(SQLITE3_PKEY_ERROR) ||
|
22
|
-
|
23
|
-
message.include?(MYSQL5_INDEX_ERROR) ||
|
24
|
-
message.include?(MYSQL8_INDEX_ERROR) ||
|
25
|
-
message.include?(POSTGRES_INDEX_ERROR) ||
|
26
|
-
message.include?(SQLITE3_INDEX_ERROR)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RubyEventStore
|
4
|
-
module ROM
|
5
|
-
module SQL
|
6
|
-
module Relations
|
7
|
-
class Events < ::ROM::Relation[:sql]
|
8
|
-
schema(:event_store_events, as: :events, infer: true) do
|
9
|
-
attribute :data, RubyEventStore::ROM::Types::SerializedRecordSerializer,
|
10
|
-
read: RubyEventStore::ROM::Types::SerializedRecordDeserializer
|
11
|
-
attribute :metadata, RubyEventStore::ROM::Types::SerializedRecordSerializer,
|
12
|
-
read: RubyEventStore::ROM::Types::SerializedRecordDeserializer
|
13
|
-
attribute :created_at, RubyEventStore::ROM::Types::DateTime
|
14
|
-
end
|
15
|
-
|
16
|
-
def create_changeset(tuples)
|
17
|
-
events.changeset(Changesets::CreateEvents, tuples)
|
18
|
-
end
|
19
|
-
|
20
|
-
def update_changeset(tuples)
|
21
|
-
events.changeset(Changesets::UpdateEvents, tuples)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,72 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RubyEventStore
|
4
|
-
module ROM
|
5
|
-
module SQL
|
6
|
-
module Relations
|
7
|
-
class StreamEntries < ::ROM::Relation[:sql]
|
8
|
-
schema(:event_store_events_in_streams, as: :stream_entries, infer: true) do
|
9
|
-
attribute :created_at, RubyEventStore::ROM::Types::DateTime
|
10
|
-
|
11
|
-
associations do
|
12
|
-
belongs_to :events, as: :event, foreign_key: :event_id
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
alias take limit
|
17
|
-
|
18
|
-
SERIALIZED_GLOBAL_STREAM_NAME = 'all'.freeze
|
19
|
-
|
20
|
-
def create_changeset(tuples)
|
21
|
-
changeset(ROM::Changesets::CreateStreamEntries, tuples)
|
22
|
-
end
|
23
|
-
|
24
|
-
def by_stream(stream)
|
25
|
-
where(stream: normalize_stream_name(stream))
|
26
|
-
end
|
27
|
-
|
28
|
-
def by_event_id(event_id)
|
29
|
-
where(event_id: event_id)
|
30
|
-
end
|
31
|
-
|
32
|
-
def by_event_type(types)
|
33
|
-
join(:events).where(event_type: types)
|
34
|
-
end
|
35
|
-
|
36
|
-
def by_stream_and_event_id(stream, event_id)
|
37
|
-
where(stream: normalize_stream_name(stream), event_id: event_id).one!
|
38
|
-
end
|
39
|
-
|
40
|
-
def max_position(stream)
|
41
|
-
by_stream(stream).select(:position).order(Sequel.desc(:position)).first
|
42
|
-
end
|
43
|
-
|
44
|
-
DIRECTION_MAP = {
|
45
|
-
forward: %i[asc > <],
|
46
|
-
backward: %i[desc < >]
|
47
|
-
}.freeze
|
48
|
-
|
49
|
-
def ordered(direction, stream, offset_entry_id = nil, stop_entry_id = nil)
|
50
|
-
order, operator_offset, operator_stop = DIRECTION_MAP[direction]
|
51
|
-
|
52
|
-
raise ArgumentError, 'Direction must be :forward or :backward' if order.nil?
|
53
|
-
|
54
|
-
order_columns = %i[position id]
|
55
|
-
order_columns.delete(:position) if stream.global?
|
56
|
-
|
57
|
-
query = by_stream(stream)
|
58
|
-
query = query.where { id.public_send(operator_offset, offset_entry_id) } if offset_entry_id
|
59
|
-
query = query.where { id.public_send(operator_stop, stop_entry_id) } if stop_entry_id
|
60
|
-
query.order { |r| order_columns.map { |c| r[:stream_entries][c].public_send(order) } }
|
61
|
-
end
|
62
|
-
|
63
|
-
private
|
64
|
-
|
65
|
-
def normalize_stream_name(stream)
|
66
|
-
stream.global? ? SERIALIZED_GLOBAL_STREAM_NAME : stream.name
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|