ruby_event_store-rom 1.3.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/lib/ruby_event_store/rom/changesets/create_events.rb +10 -18
  4. data/lib/ruby_event_store/rom/changesets/create_stream_entries.rb +3 -12
  5. data/lib/ruby_event_store/rom/changesets/update_events.rb +33 -19
  6. data/lib/ruby_event_store/rom/event_repository.rb +65 -61
  7. data/lib/ruby_event_store/rom/index_violation_detector.rb +25 -0
  8. data/lib/ruby_event_store/rom/mappers/event_to_serialized_record.rb +10 -6
  9. data/lib/ruby_event_store/rom/mappers/stream_entry_to_serialized_record.rb +11 -6
  10. data/lib/ruby_event_store/rom/rake_task.rb +5 -0
  11. data/lib/ruby_event_store/rom/relations/events.rb +78 -0
  12. data/lib/ruby_event_store/rom/relations/stream_entries.rb +83 -0
  13. data/lib/ruby_event_store/rom/repositories/events.rb +55 -30
  14. data/lib/ruby_event_store/rom/repositories/stream_entries.rb +15 -16
  15. data/lib/ruby_event_store/rom/tasks/migration_tasks.rake +36 -0
  16. data/lib/ruby_event_store/rom/types.rb +16 -14
  17. data/lib/ruby_event_store/rom/unit_of_work.rb +28 -13
  18. data/lib/ruby_event_store/rom/version.rb +1 -1
  19. data/lib/ruby_event_store/rom.rb +28 -103
  20. data/lib/ruby_event_store-rom.rb +1 -1
  21. metadata +31 -49
  22. data/.rubocop.yml +0 -1
  23. data/.rubocop_todo.yml +0 -84
  24. data/CHANGELOG.md +0 -9
  25. data/Gemfile +0 -12
  26. data/Makefile +0 -57
  27. data/Rakefile +0 -20
  28. data/db/migrate/20180327044629_create_ruby_event_store_tables.rb +0 -54
  29. data/db/migrate/20181026152045_index_by_event_type.rb +0 -9
  30. data/lib/ruby_event_store/rom/adapters/memory/changesets/create_events.rb +0 -19
  31. data/lib/ruby_event_store/rom/adapters/memory/changesets/create_stream_entries.rb +0 -19
  32. data/lib/ruby_event_store/rom/adapters/memory/changesets/update_events.rb +0 -18
  33. data/lib/ruby_event_store/rom/adapters/memory/relations/events.rb +0 -56
  34. data/lib/ruby_event_store/rom/adapters/memory/relations/stream_entries.rb +0 -114
  35. data/lib/ruby_event_store/rom/adapters/memory/unit_of_work.rb +0 -36
  36. data/lib/ruby_event_store/rom/adapters/sql/changesets/create_events.rb +0 -15
  37. data/lib/ruby_event_store/rom/adapters/sql/changesets/update_events.rb +0 -41
  38. data/lib/ruby_event_store/rom/adapters/sql/index_violation_detector.rb +0 -31
  39. data/lib/ruby_event_store/rom/adapters/sql/rake_task.rb +0 -5
  40. data/lib/ruby_event_store/rom/adapters/sql/relations/events.rb +0 -27
  41. data/lib/ruby_event_store/rom/adapters/sql/relations/stream_entries.rb +0 -72
  42. data/lib/ruby_event_store/rom/adapters/sql/tasks/migration_tasks.rake +0 -36
  43. data/lib/ruby_event_store/rom/memory.rb +0 -82
  44. data/lib/ruby_event_store/rom/sql.rb +0 -169
  45. data/lib/ruby_event_store/rom/tuple_uniqueness_error.rb +0 -21
  46. data/lib/ruby_event_store/spec/rom/event_repository_lint.rb +0 -176
  47. data/lib/ruby_event_store/spec/rom/relations/events_lint.rb +0 -75
  48. data/lib/ruby_event_store/spec/rom/relations/stream_entries_lint.rb +0 -198
  49. data/lib/ruby_event_store/spec/rom/spec_helper_lint.rb +0 -15
  50. data/lib/ruby_event_store/spec/rom/unit_of_work_lint.rb +0 -37
  51. data/ruby_event_store-rom.gemspec +0 -37
data/.rubocop_todo.yml DELETED
@@ -1,84 +0,0 @@
1
- # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2018-12-29 04:25:35 -0500 using RuboCop version 0.61.1.
4
- # The point is for the user to remove these configuration records
5
- # one by one as the offenses are removed from the code base.
6
- # Note that changes in the inspected code, or installation of new
7
- # versions of RuboCop, may require this file to be generated again.
8
-
9
- # Offense count: 3
10
- Lint/HandleExceptions:
11
- Exclude:
12
- - 'Rakefile'
13
- - 'lib/ruby_event_store/rom.rb'
14
- - 'spec/spec_helper.rb'
15
-
16
- # Offense count: 6
17
- Metrics/AbcSize:
18
- Max: 34
19
-
20
- # Offense count: 8
21
- # Configuration parameters: CountComments, ExcludedMethods.
22
- # ExcludedMethods: refine
23
- Metrics/BlockLength:
24
- Max: 146
25
-
26
- # Offense count: 2
27
- Metrics/CyclomaticComplexity:
28
- Max: 8
29
-
30
- # Offense count: 6
31
- # Configuration parameters: CountComments, ExcludedMethods.
32
- Metrics/MethodLength:
33
- Max: 30
34
-
35
- # Offense count: 1
36
- # Configuration parameters: CountComments.
37
- Metrics/ModuleLength:
38
- Max: 130
39
-
40
- # Offense count: 2
41
- Metrics/PerceivedComplexity:
42
- Max: 11
43
-
44
- # Offense count: 1
45
- # Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
46
- # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
47
- Naming/FileName:
48
- Exclude:
49
- - 'lib/ruby_event_store-rom.rb'
50
-
51
- # Offense count: 3
52
- # Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist, MethodDefinitionMacros.
53
- # NamePrefix: is_, has_, have_
54
- # NamePrefixBlacklist: is_, has_, have_
55
- # NameWhitelist: is_a?
56
- # MethodDefinitionMacros: define_method, define_singleton_method
57
- Naming/PredicateName:
58
- Exclude:
59
- - 'spec/**/*'
60
- - 'lib/ruby_event_store/rom/event_repository.rb'
61
- - 'lib/ruby_event_store/rom/memory.rb'
62
- - 'lib/ruby_event_store/rom/sql.rb'
63
-
64
- # Offense count: 16
65
- # Cop supports --auto-correct.
66
- # Configuration parameters: AutoCorrect, EnforcedStyle.
67
- # SupportedStyles: nested, compact
68
- Style/ClassAndModuleChildren:
69
- Enabled: false
70
-
71
- # Offense count: 25
72
- Style/Documentation:
73
- Enabled: false
74
-
75
- # Offense count: 2
76
- Style/MultilineBlockChain:
77
- Exclude:
78
- - 'spec/rom/adapters/memory/relations/stream_entries_spec.rb'
79
-
80
- # Offense count: 136
81
- # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
82
- # URISchemes: http, https
83
- Metrics/LineLength:
84
- Max: 151
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,9 +0,0 @@
1
- require 'rom/sql'
2
-
3
- ::ROM::SQL.migration do
4
- change do
5
- alter_table(:event_store_events) do
6
- add_index :event_type
7
- end
8
- end
9
- 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,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RubyEventStore
4
- module ROM
5
- module SQL
6
- module Changesets
7
- class CreateEvents < ROM::Changesets::CreateEvents
8
- def commit
9
- relation.multi_insert(to_a)
10
- end
11
- end
12
- end
13
- end
14
- end
15
- 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,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rom/sql/rake_task'
4
- require 'ruby_event_store/rom/sql'
5
- load 'ruby_event_store/rom/adapters/sql/tasks/migration_tasks.rake'
@@ -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