ruby_event_store-rom 0.35.0 → 0.36.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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/.rubocop_todo.yml +84 -0
  4. data/Gemfile +4 -4
  5. data/Makefile +3 -0
  6. data/Rakefile +3 -3
  7. data/db/migrate/20180327044629_create_ruby_event_store_tables.rb +17 -8
  8. data/lib/ruby_event_store/rom.rb +19 -16
  9. data/lib/ruby_event_store/rom/adapters/memory/changesets/create_events.rb +17 -0
  10. data/lib/ruby_event_store/rom/adapters/memory/changesets/create_stream_entries.rb +17 -0
  11. data/lib/ruby_event_store/rom/adapters/memory/changesets/update_events.rb +16 -0
  12. data/lib/ruby_event_store/rom/adapters/memory/relations/events.rb +14 -5
  13. data/lib/ruby_event_store/rom/adapters/memory/relations/stream_entries.rb +8 -4
  14. data/lib/ruby_event_store/rom/adapters/memory/unit_of_work.rb +6 -21
  15. data/lib/ruby_event_store/rom/adapters/sql/changesets/create_events.rb +13 -0
  16. data/lib/ruby_event_store/rom/adapters/sql/changesets/update_events.rb +39 -0
  17. data/lib/ruby_event_store/rom/adapters/sql/index_violation_detector.rb +15 -16
  18. data/lib/ruby_event_store/rom/adapters/sql/relations/events.rb +13 -1
  19. data/lib/ruby_event_store/rom/adapters/sql/relations/stream_entries.rb +8 -4
  20. data/lib/ruby_event_store/rom/adapters/sql/tasks/migration_tasks.rake +16 -3
  21. data/lib/ruby_event_store/rom/changesets/create_events.rb +29 -0
  22. data/lib/ruby_event_store/rom/changesets/create_stream_entries.rb +21 -0
  23. data/lib/ruby_event_store/rom/changesets/update_events.rb +29 -0
  24. data/lib/ruby_event_store/rom/event_repository.rb +16 -6
  25. data/lib/ruby_event_store/rom/mappers/event_to_serialized_record.rb +1 -1
  26. data/lib/ruby_event_store/rom/mappers/stream_entry_to_serialized_record.rb +1 -1
  27. data/lib/ruby_event_store/rom/memory.rb +15 -3
  28. data/lib/ruby_event_store/rom/repositories/events.rb +18 -30
  29. data/lib/ruby_event_store/rom/repositories/stream_entries.rb +17 -18
  30. data/lib/ruby_event_store/rom/sql.rb +62 -12
  31. data/lib/ruby_event_store/rom/types.rb +13 -0
  32. data/lib/ruby_event_store/rom/unit_of_work.rb +1 -1
  33. data/lib/ruby_event_store/rom/version.rb +1 -1
  34. data/lib/ruby_event_store/spec/rom/event_repository_lint.rb +55 -90
  35. data/lib/ruby_event_store/spec/rom/relations/events_lint.rb +12 -12
  36. data/lib/ruby_event_store/spec/rom/relations/stream_entries_lint.rb +44 -44
  37. data/lib/ruby_event_store/spec/rom/spec_helper_lint.rb +1 -1
  38. data/lib/ruby_event_store/spec/rom/unit_of_work_lint.rb +1 -1
  39. data/ruby_event_store-rom.gemspec +12 -13
  40. metadata +40 -31
  41. data/lib/ruby_event_store/rom/adapters/sql/unit_of_work.rb +0 -37
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3760c9bc0e5cbf84b824cab9d38fc9ab85db2aea9fca8cc1ead956a67504d08f
4
- data.tar.gz: 520f6ee4fee9f63018c547276691f1c9b2c23ae55dd5384279d55302f2c7d3e8
3
+ metadata.gz: b0657b44931013a36c0db15e739957207921bc1344dceffd3046c6ab7636de06
4
+ data.tar.gz: 52a47bed2d4bd98d83928a28f26e85446b7c1ee3cf574f30cbe773dd8ca08071
5
5
  SHA512:
6
- metadata.gz: df638ec5c1bbb2ec850675769b601df6660c89ce5c1b98cef2a7fe3c05065c86c3176163d2fbd3eddaab116e6d63656a95e711a65acc75877e027ec9194e77f3
7
- data.tar.gz: b1df8c60802b4cd81e564da16f707d2b6baa3929507d072c94a7c29196789954150073a4d1b3d2f766663b7c74ddc2a18c1bdc1a92be6f065e9330e164bed23c
6
+ metadata.gz: 89d84ef8613d86632e570c0179ee3ef273eecd73c0f0e9779e237b0512c0d7690a44a958e5feccf34191bbbfddd10d4f479a520d96d450bf40506483db6a398a
7
+ data.tar.gz: bc6bfc3cc17b4568b172f15eae603a888d0dcdfbd019a5b5b9620cde86a09c5f1511dbe7ee96611674fa6e175a0008ee59554ce90f3bdefba3fe3ab8f61706f0
@@ -0,0 +1 @@
1
+ inherit_from: .rubocop_todo.yml
@@ -0,0 +1,84 @@
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/Gemfile CHANGED
@@ -3,9 +3,9 @@ gemspec
3
3
 
4
4
  eval_gemfile File.expand_path('../lib/Gemfile.shared', __dir__)
5
5
 
6
+ gem 'childprocess'
7
+ gem 'fakefs', '~> 0.11.2'
8
+ gem 'mysql2', '>= 0.4.10'
9
+ gem 'pg', '>= 0.21'
6
10
  gem 'ruby_event_store', path: '../ruby_event_store'
7
11
  gem 'sqlite3', '1.3.13'
8
- gem 'pg', '>= 0.21'
9
- gem 'mysql2', '>= 0.4.10'
10
- gem 'fakefs', '~> 0.11.2'
11
- gem 'childprocess'
data/Makefile CHANGED
@@ -8,6 +8,9 @@ IGNORE = RubyEventStore::ROM::EventRepository\#initialize \
8
8
  RubyEventStore::ROM::EventRepository\#last_stream_event \
9
9
  RubyEventStore::ROM::Repositories::Events\#find_nonexistent_pks \
10
10
  RubyEventStore::ROM::Repositories::StreamEntries\#create_changeset \
11
+ RubyEventStore::ROM::Changesets::CreateStreamEntries::Defaults.included \
12
+ RubyEventStore::ROM::Changesets::CreateEvents::Defaults.included \
13
+ RubyEventStore::ROM::Changesets::UpdateEvents::Defaults.included \
11
14
  RubyEventStore::ROM::Env\#handle_error \
12
15
  RubyEventStore::ROM::Env\#initialize \
13
16
  RubyEventStore::ROM::Env\#register_error_handler \
data/Rakefile CHANGED
@@ -5,16 +5,16 @@ require 'ruby_event_store/rom/adapters/sql/rake_task'
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
  task default: [:ci]
7
7
 
8
- desc "Run CI tasks"
8
+ desc 'Run CI tasks'
9
9
  task ci: [:spec]
10
10
 
11
11
  begin
12
- require "rubocop/rake_task"
12
+ require 'rubocop/rake_task'
13
13
 
14
14
  Rake::Task[:default].enhance [:rubocop]
15
15
 
16
16
  RuboCop::RakeTask.new do |task|
17
- task.options << "--display-cop-names"
17
+ task.options << '--display-cop-names'
18
18
  end
19
19
  rescue LoadError
20
20
  end
@@ -3,8 +3,14 @@ require 'rom/sql'
3
3
  ::ROM::SQL.migration do
4
4
  change do
5
5
  postgres = database_type =~ /postgres/
6
- sqlite = database_type =~ /sqlite/
7
-
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
+
8
14
  run 'CREATE EXTENSION IF NOT EXISTS pgcrypto;' if postgres
9
15
 
10
16
  create_table? :event_store_events_in_streams do
@@ -20,7 +26,7 @@ require 'rom/sql'
20
26
  end
21
27
 
22
28
  column :created_at, DateTime, null: false, index: 'index_event_store_events_in_streams_on_created_at'
23
-
29
+
24
30
  index %i[stream position], unique: true, name: 'index_event_store_events_in_streams_on_stream_and_position'
25
31
  index %i[stream event_id], unique: true, name: 'index_event_store_events_in_streams_on_stream_and_event_id'
26
32
  end
@@ -33,13 +39,16 @@ require 'rom/sql'
33
39
  end
34
40
 
35
41
  column :event_type, String, null: false
36
- column :metadata, String, text: true
37
- column :data, String, text: true, null: false
38
- column :created_at, DateTime, null: false, index: 'index_event_store_events_on_created_at'
39
42
 
40
- if sqlite # TODO: Is this relevant without ActiveRecord?
41
- index :id, unique: true
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
42
49
  end
50
+
51
+ column :created_at, DateTime, null: false, index: 'index_event_store_events_on_created_at'
43
52
  end
44
53
  end
45
54
  end
@@ -2,7 +2,11 @@ require 'rom-changeset'
2
2
  require 'rom-mapper'
3
3
  require 'rom-repository'
4
4
  require 'ruby_event_store'
5
+ require 'ruby_event_store/rom/types'
5
6
  require 'ruby_event_store/rom/event_repository'
7
+ require 'ruby_event_store/rom/changesets/create_events'
8
+ require 'ruby_event_store/rom/changesets/update_events'
9
+ require 'ruby_event_store/rom/changesets/create_stream_entries'
6
10
  require 'ruby_event_store/rom/tuple_uniqueness_error'
7
11
  require 'ruby_event_store/rom/unit_of_work'
8
12
  require 'ruby_event_store/rom/version'
@@ -11,10 +15,10 @@ module RubyEventStore
11
15
  module ROM
12
16
  class Env
13
17
  attr_accessor :container
14
-
18
+
15
19
  def initialize(container)
16
20
  @container = container
17
-
21
+
18
22
  container.register(:unique_violation_error_handlers, Set.new)
19
23
  container.register(:not_found_error_handlers, Set.new)
20
24
  container.register(:logger, Logger.new(STDOUT).tap { |logger| logger.level = Logger::WARN })
@@ -26,25 +30,24 @@ module RubyEventStore
26
30
 
27
31
  def unit_of_work(&block)
28
32
  options = container[:unit_of_work_options].dup
29
- options.delete(:class){UnitOfWork}.new(rom: self).call(**options, &block)
33
+ options.delete(:class) { UnitOfWork }.new(rom: self).call(**options, &block)
30
34
  end
31
35
 
32
36
  def register_unit_of_work_options(options)
33
37
  container.register(:unit_of_work_options, options)
34
38
  end
35
-
39
+
36
40
  def register_error_handler(type, handler)
37
41
  container[:"#{type}_error_handlers"] << handler
38
42
  end
39
-
43
+
40
44
  def handle_error(type, *args, swallow: [])
41
45
  yield
42
- rescue => ex
46
+ rescue StandardError => ex
43
47
  begin
44
- container[:"#{type}_error_handlers"].each{ |h| h.call(ex, *args) }
48
+ container[:"#{type}_error_handlers"].each { |h| h.call(ex, *args) }
45
49
  raise ex
46
50
  rescue *swallow
47
- # swallow
48
51
  end
49
52
  end
50
53
  end
@@ -52,7 +55,7 @@ module RubyEventStore
52
55
  class << self
53
56
  # Set to a default instance
54
57
  attr_accessor :env
55
-
58
+
56
59
  def configure(adapter_name, database_uri = ENV['DATABASE_URL'], &block)
57
60
  if adapter_name.is_a?(::ROM::Configuration)
58
61
  # Call config block manually
@@ -61,20 +64,20 @@ module RubyEventStore
61
64
  Env.new ::ROM.container(adapter_name, database_uri, &block)
62
65
  end
63
66
  end
64
-
67
+
65
68
  def setup(*args, &block)
66
69
  configure(*args) do |config|
67
70
  setup_defaults(config)
68
- block.call(config) if block
71
+ yield(config) if block
69
72
  end.tap(&method(:configure_defaults))
70
73
  end
71
74
 
72
- private
73
-
75
+ private
76
+
74
77
  def setup_defaults(config)
75
78
  require_relative 'rom/repositories/stream_entries'
76
79
  require_relative 'rom/repositories/events'
77
-
80
+
78
81
  config.register_mapper(ROM::Mappers::EventToSerializedRecord)
79
82
  config.register_mapper(ROM::Mappers::StreamEntryToSerializedRecord)
80
83
 
@@ -84,10 +87,10 @@ module RubyEventStore
84
87
  end
85
88
 
86
89
  def configure_defaults(env)
87
- env.register_error_handler :not_found, -> (ex, event_id) {
90
+ env.register_error_handler :not_found, lambda { |ex, event_id|
88
91
  case ex
89
92
  when ::ROM::TupleCountMismatchError
90
- raise EventNotFound.new(event_id)
93
+ raise EventNotFound, event_id
91
94
  end
92
95
  }
93
96
 
@@ -0,0 +1,17 @@
1
+ module RubyEventStore
2
+ module ROM
3
+ module Memory
4
+ module Changesets
5
+ class CreateEvents < ROM::Changesets::CreateEvents
6
+ def commit
7
+ relation.by_pk(to_a.map { |e| e[:id] }).each do |tuple|
8
+ raise TupleUniquenessError.for_event_id(tuple[:id])
9
+ end
10
+
11
+ super
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module RubyEventStore
2
+ module ROM
3
+ module Memory
4
+ module Changesets
5
+ class CreateStreamEntries < ROM::Changesets::CreateStreamEntries
6
+ def commit
7
+ to_a.each do |tuple|
8
+ relation.send(:verify_uniquness!, tuple)
9
+ end
10
+
11
+ super
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ module RubyEventStore
2
+ module ROM
3
+ module Memory
4
+ module Changesets
5
+ class UpdateEvents < ROM::Changesets::UpdateEvents
6
+ def commit
7
+ to_a.each do |params|
8
+ attributes = command.input[params].to_h.delete_if { |k, v| k == :created_at && v.nil? }
9
+ relation.by_pk(params.fetch(:id)).dataset.map { |tuple| tuple.update(attributes) }
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -8,18 +8,26 @@ module RubyEventStore
8
8
  attribute :event_type, ::ROM::Types::Strict::String
9
9
  attribute :metadata, ::ROM::Types::Strict::String.optional
10
10
  attribute :data, ::ROM::Types::Strict::String
11
- attribute :created_at, ::ROM::Types::Strict::Time.default { Time.now }
11
+ attribute :created_at, RubyEventStore::ROM::Types::DateTime
12
+ end
13
+
14
+ def create_changeset(tuples)
15
+ events.changeset(Changesets::CreateEvents, tuples)
16
+ end
17
+
18
+ def update_changeset(tuples)
19
+ events.changeset(Changesets::UpdateEvents, tuples)
12
20
  end
13
21
 
14
22
  def insert(tuple)
15
23
  verify_uniquness!(tuple)
16
24
  super
17
25
  end
18
-
26
+
19
27
  def for_stream_entries(_assoc, stream_entries)
20
28
  restrict(id: stream_entries.map { |e| e[:event_id] })
21
29
  end
22
-
30
+
23
31
  def by_pk(id)
24
32
  restrict(id: id)
25
33
  end
@@ -31,11 +39,12 @@ module RubyEventStore
31
39
  def pluck(name)
32
40
  map { |e| e[name] }
33
41
  end
34
-
35
- private
42
+
43
+ private
36
44
 
37
45
  def verify_uniquness!(tuple)
38
46
  return unless by_pk(tuple[:id]).exist?
47
+
39
48
  raise TupleUniquenessError.for_event_id(tuple[:id])
40
49
  end
41
50
  end
@@ -4,11 +4,11 @@ module RubyEventStore
4
4
  module Relations
5
5
  class StreamEntries < ::ROM::Relation[:memory]
6
6
  schema(:stream_entries) do
7
- attribute :id, ::ROM::Types::Strict::Int.meta(primary_key: true).default { RubyEventStore::ROM::Memory.fetch_next_id }
7
+ attribute(:id, ::ROM::Types::Strict::Int.meta(primary_key: true).default { RubyEventStore::ROM::Memory.fetch_next_id })
8
8
  attribute :stream, ::ROM::Types::Strict::String
9
9
  attribute :position, ::ROM::Types::Strict::Int.optional
10
10
  attribute :event_id, ::ROM::Types::Strict::String.meta(foreign_key: true, relation: :events)
11
- attribute :created_at, ::ROM::Types::Strict::Time.default { Time.now }
11
+ attribute :created_at, RubyEventStore::ROM::Types::DateTime
12
12
 
13
13
  associations do
14
14
  belongs_to :events, as: :event, foreign_key: :event_id, override: true, view: :for_stream_entries
@@ -23,6 +23,10 @@ module RubyEventStore
23
23
 
24
24
  SERIALIZED_GLOBAL_STREAM_NAME = 'all'.freeze
25
25
 
26
+ def create_changeset(tuples)
27
+ changeset(Changesets::CreateStreamEntries, tuples)
28
+ end
29
+
26
30
  def offset(num)
27
31
  num.zero? ? self : new(dataset.slice(num..-1) || [])
28
32
  end
@@ -61,7 +65,7 @@ module RubyEventStore
61
65
  end
62
66
 
63
67
  DIRECTION_MAP = {
64
- forward: [false, :>],
68
+ forward: [false, :>],
65
69
  backward: [true, :<]
66
70
  }.freeze
67
71
 
@@ -81,7 +85,7 @@ module RubyEventStore
81
85
  query
82
86
  end
83
87
 
84
- private
88
+ private
85
89
 
86
90
  # Verifies uniqueness of [stream, event_id] and [stream, position]
87
91
  def verify_uniquness!(tuple)
@@ -6,39 +6,24 @@ module RubyEventStore
6
6
  @mutex ||= Mutex.new
7
7
  end
8
8
 
9
- def commit!(gateway, changesets, **options)
9
+ def commit!(_gateway, changesets, **_options)
10
10
  self.class.mutex.synchronize do
11
11
  committed = []
12
-
12
+
13
13
  begin
14
- while changesets.size > 0
14
+ until changesets.empty?
15
15
  changeset = changesets.shift
16
16
  relation = env.container.relations[changeset.relation.name]
17
17
 
18
- case changeset
19
- when ROM::Repositories::Events::Create
20
- relation.by_pk(changeset.to_a.map{ |e| e[:id] }).each do |tuple|
21
- raise TupleUniquenessError.for_event_id(tuple[:id])
22
- end
23
- when ROM::Repositories::StreamEntries::Create
24
- changeset.to_a.each do |tuple|
25
- relation.send(:verify_uniquness!, tuple)
26
- end
27
- else
28
- raise ArgumentError, 'Unknown changeset'
29
- end
30
-
31
18
  committed << [changeset, relation]
32
19
 
33
20
  changeset.commit
34
21
  end
35
22
  rescue StandardError
36
- committed.reverse.each do |changeset, relation|
37
- relation
38
- .restrict(id: changeset.to_a.map { |e| e[:id] })
39
- .command(:delete, result: :many).call
23
+ committed.reverse_each do |c, r|
24
+ r.restrict(id: c.to_a.map { |e| e[:id] }).command(:delete, result: :many).call
40
25
  end
41
-
26
+
42
27
  raise
43
28
  end
44
29
  end