ruby_event_store 0.34.0 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 212817e54f12a8231a77260d38f5c41980d0e0c4d465ac3fae5ef49fb5b5301d
4
- data.tar.gz: c24731e1641aa7874d8417acda1550cd182df6d24c79f2f0906bdbb17b0e8e8f
3
+ metadata.gz: a2e4768baf6a615d130234f71b2eeeeea911baafcab466651e42e4f5873430a3
4
+ data.tar.gz: 587f48214166735f91685638143133723cb7c3e2e46a3ec657490ce7c13cda00
5
5
  SHA512:
6
- metadata.gz: d13612719037ba3a5e703f9eb34280968957056a5bd4f53c169817cdeec59c1965c984aeb322843f826e7baa875cd25690f7073900718a0ae2c86fd747d0718e
7
- data.tar.gz: eb230b36b3103386bbe315765a165842d1bc287400f6543f8c9b0625a42c7e85e9cbb8583b4fd8897f3429e26bdb021243aac6954802155d8417e37fd8f57063
6
+ metadata.gz: 2115d731ca0d1f6e6b9eb26d4a8cf8e8ea41c634bb521de9cfc2b181c3fec7f98d4b0a33667befeb16343247fdae1315cf543ac77ab4808bf6cb23740f91233f
7
+ data.tar.gz: 71473199da981d2832cc60fac2887a4222b4a6606f15f0bf7356414ea11bdb3abd80ca38baf3f07cb377c6afe4e69662db0c97d3bdf5fbe364253d2d713b9fcd
data/Gemfile CHANGED
@@ -1,4 +1,11 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
3
 
4
+ eval_gemfile File.expand_path('../lib/Gemfile.shared', __dir__)
5
+
4
6
  gem 'protobuf_nested_struct'
7
+ gem 'parser'
8
+ gem 'unparser'
9
+ gem 'astrolabe'
10
+ gem 'google-protobuf', '~> 3.5.1.2'
11
+ gem 'activesupport', '~> 5.0'
data/Makefile CHANGED
@@ -14,57 +14,11 @@ IGNORE = RubyEventStore::InMemoryRepository\#append_with_synchronize \
14
14
  RubyEventStore::SpecificationResult\#count \
15
15
  RubyEventStore::SpecificationResult\#direction \
16
16
  RubyEventStore::SpecificationResult\#stream_name \
17
- RubyEventStore::SpecificationResult\#global_stream? \
18
-
19
-
17
+ RubyEventStore::SpecificationResult\#global_stream?
20
18
  SUBJECT ?= RubyEventStore*
21
19
 
22
- install: ## Install gem dependencies
23
- @echo "Installing gem dependencies"
24
- @bundle install
25
-
26
- remove-lock:
27
- @echo "Removing resolved dependency versions"
28
- -rm Gemfile.lock
29
-
30
- reinstall: remove-lock install ## Removing resolved dependency versions
31
-
32
- test: ## Run unit tests
33
- @echo "Running unit tests"
34
- @bundle exec rspec
35
-
36
- mutate: test ## Run mutation tests
37
- @echo "Running mutation tests"
38
- @MUTATING=true bundle exec mutant --include lib \
39
- $(addprefix --require ,$(REQUIRE)) \
40
- $(addprefix --ignore-subject ,$(IGNORE)) \
41
- --use rspec "$(SUBJECT)"
42
-
43
- mutate-fast: ## Run mutation tests with --fail-fast
44
- @echo "Running mutation tests"
45
- @MUTATING=true bundle exec mutant --include lib \
46
- $(addprefix --require ,$(REQUIRE)) \
47
- $(addprefix --ignore-subject ,$(IGNORE)) \
48
- --fail-fast \
49
- --use rspec "$(SUBJECT)"
50
-
51
- build:
52
- @echo "Building gem package"
53
- @gem build -V $(GEM_NAME).gemspec
54
- @mkdir -p pkg/
55
- @mv $(GEM_NAME)-$(GEM_VERSION).gem pkg/
56
-
57
- push:
58
- @echo "Pushing package to RubyGems"
59
- @gem push -k dev_arkency pkg/$(GEM_NAME)-$(GEM_VERSION).gem
60
-
61
- clean:
62
- @echo "Removing previously built package"
63
- -rm pkg/$(GEM_NAME)-$(GEM_VERSION).gem
64
-
65
- help:
66
- @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
67
-
68
- .PHONY: help
69
- .DEFAULT_GOAL := help
70
-
20
+ include ../lib/install.mk
21
+ include ../lib/test.mk
22
+ include ../lib/mutant.mk
23
+ include ../lib/gem.mk
24
+ include ../lib/help.mk
@@ -14,6 +14,7 @@ require 'ruby_event_store/event'
14
14
  require 'ruby_event_store/stream'
15
15
  require 'ruby_event_store/expected_version'
16
16
  require 'ruby_event_store/serialized_record'
17
+ require 'ruby_event_store/transform_keys'
17
18
  require 'ruby_event_store/mappers/default'
18
19
  require 'ruby_event_store/mappers/protobuf'
19
20
  require 'ruby_event_store/mappers/null_mapper'
@@ -8,8 +8,7 @@ module RubyEventStore
8
8
 
9
9
  def each
10
10
  return to_enum unless block_given?
11
- (0...total_limit).step(batch_size) do |batch_offset|
12
- batch_offset = Integer(batch_offset)
11
+ 0.step(total_limit - 1, batch_size) do |batch_offset|
13
12
  batch_limit = [batch_size, total_limit - batch_offset].min
14
13
  result = reader.call(batch_offset, batch_limit)
15
14
 
@@ -32,12 +32,7 @@ module RubyEventStore
32
32
  end
33
33
 
34
34
  def read(spec)
35
- events = spec.stream.global? ? global : stream_of(spec.stream.name)
36
- events = events.select{|e| spec.with_ids.any?{|x| x.eql?(e.event_id)}} if spec.with_ids?
37
- events = events.select{|e| spec.with_types.any?{|x| x.eql?(e.event_type)}} if spec.with_types?
38
- events = events.reverse if spec.backward?
39
- events = events.drop(index_of(events, spec.start) + 1) unless spec.head?
40
- events = events[0...spec.limit] if spec.limit?
35
+ events = read_scope(spec)
41
36
  if spec.batched?
42
37
  batch_reader = ->(offset, limit) { events.drop(offset).take(limit) }
43
38
  BatchEnumerator.new(spec.batch_size, events.size, batch_reader).each
@@ -50,6 +45,10 @@ module RubyEventStore
50
45
  end
51
46
  end
52
47
 
48
+ def count(spec)
49
+ read_scope(spec).count
50
+ end
51
+
53
52
  def update_messages(messages)
54
53
  messages.each do |new_msg|
55
54
  location = global.index{|m| new_msg.event_id.eql?(m.event_id)} or raise EventNotFound.new(new_msg.event_id)
@@ -68,6 +67,15 @@ module RubyEventStore
68
67
  end
69
68
 
70
69
  private
70
+ def read_scope(spec)
71
+ events = spec.stream.global? ? global : stream_of(spec.stream.name)
72
+ events = events.select{|e| spec.with_ids.any?{|x| x.eql?(e.event_id)}} if spec.with_ids?
73
+ events = events.select{|e| spec.with_types.any?{|x| x.eql?(e.event_type)}} if spec.with_types?
74
+ events = events.reverse if spec.backward?
75
+ events = events.drop(index_of(events, spec.start) + 1) unless spec.head?
76
+ events = events[0...spec.limit] if spec.limit?
77
+ events
78
+ end
71
79
 
72
80
  def read_event(event_id)
73
81
  global.find {|e| event_id.eql?(e.event_id)} or raise EventNotFound.new(event_id)
@@ -37,6 +37,12 @@ module RubyEventStore
37
37
  end
38
38
  end
39
39
 
40
+ def count(specification)
41
+ instrumentation.instrument("count.repository.rails_event_store", specification: specification) do
42
+ repository.count(specification)
43
+ end
44
+ end
45
+
40
46
  def update_messages(messages)
41
47
  instrumentation.instrument("update_messages.repository.rails_event_store", messages: messages) do
42
48
  repository.update_messages(messages)
@@ -21,20 +21,13 @@ module RubyEventStore
21
21
  event_type = events_class_remapping.fetch(record.event_type) { record.event_type }
22
22
  Object.const_get(event_type).new(
23
23
  event_id: record.event_id,
24
- metadata: symbolize(serializer.load(record.metadata)),
24
+ metadata: TransformKeys.symbolize(serializer.load(record.metadata)),
25
25
  data: serializer.load(record.data)
26
26
  )
27
27
  end
28
28
 
29
29
  private
30
-
31
30
  attr_reader :serializer, :events_class_remapping
32
-
33
- def symbolize(hash)
34
- hash.each_with_object({}) do |(k, v), memo|
35
- memo[k.to_sym] = v
36
- end
37
- end
38
31
  end
39
32
  end
40
33
  end
@@ -4,31 +4,11 @@ module RubyEventStore
4
4
  data.class.descriptor.name
5
5
  end
6
6
 
7
- def encode_with(coder)
8
- coder['event_id'] = event_id
9
- coder['metadata'] = ProtobufNestedStruct::HashMapStringValue.dump(metadata.each_with_object({}){|(k,v),h| h[k.to_s] =v })
10
- coder['data.proto'] = data.class.encode(data)
11
- coder['data.type'] = type
12
- end
13
-
14
- def init_with(coder)
15
- @event_id = coder['event_id']
16
- @metadata = Metadata.new
17
- ProtobufNestedStruct::HashMapStringValue.load(coder['metadata']).each_with_object(metadata){|(k,v),meta| meta[k.to_sym] = v }
18
- @data = pool.lookup(coder['data.type']).msgclass.decode(coder['data.proto'])
19
- end
20
-
21
7
  def ==(other_event)
22
8
  other_event.instance_of?(self.class) &&
23
9
  other_event.event_id.eql?(event_id) &&
24
10
  other_event.data == data # https://github.com/google/protobuf/issues/4455
25
11
  end
26
-
27
- private
28
-
29
- def pool
30
- Google::Protobuf::DescriptorPool.generated_pool
31
- end
32
12
  end
33
13
 
34
14
  module Mappers
@@ -41,7 +21,7 @@ module RubyEventStore
41
21
  def event_to_serialized_record(domain_event)
42
22
  SerializedRecord.new(
43
23
  event_id: domain_event.event_id,
44
- metadata: ProtobufNestedStruct::HashMapStringValue.dump(domain_event.metadata.each_with_object({}) {|(k, v), h| h[k.to_s] = v}),
24
+ metadata: ProtobufNestedStruct::HashMapStringValue.dump(TransformKeys.stringify(domain_event.metadata)),
45
25
  data: encode_data(domain_event.data),
46
26
  event_type: domain_event.type
47
27
  )
@@ -61,9 +41,7 @@ module RubyEventStore
61
41
  attr_reader :event_id_getter, :events_class_remapping
62
42
 
63
43
  def load_metadata(protobuf_metadata)
64
- ProtobufNestedStruct::HashMapStringValue.load(protobuf_metadata).each_with_object({}) do |(k, v), meta|
65
- meta[k.to_sym] = v
66
- end
44
+ TransformKeys.symbolize(ProtobufNestedStruct::HashMapStringValue.load(protobuf_metadata))
67
45
  end
68
46
 
69
47
  def load_data(event_type, protobuf_data)
@@ -85,4 +63,4 @@ module RubyEventStore
85
63
  end
86
64
  end
87
65
  end
88
- end
66
+ end
@@ -43,9 +43,9 @@ module RubyEventStore
43
43
  private
44
44
 
45
45
  def allowed_types
46
- [String, Integer, Float, Date, Time, TrueClass, FalseClass, nil]
46
+ [String, Integer, Float, Date, Time, TrueClass, FalseClass, nil, Hash, Array]
47
47
  end
48
48
 
49
49
  private_constant :SAFE_HASH_METHODS
50
50
  end
51
- end
51
+ end
@@ -977,7 +977,6 @@ module RubyEventStore
977
977
 
978
978
  specify 'can store arbitrary binary data' do
979
979
  skip unless test_binary
980
- migrate_to_binary
981
980
  binary = "\xB0"
982
981
  expect(binary.valid_encoding?).to eq(false)
983
982
  binary.force_encoding("binary")
@@ -1226,5 +1225,47 @@ module RubyEventStore
1226
1225
  expect(repository.read(specification.of_type([Type3]).result).to_a).to eq([])
1227
1226
  expect(repository.read(specification.of_type([Type1, Type2, Type3]).result).to_a).to eq([e1,e2,e3])
1228
1227
  end
1228
+
1229
+ specify do
1230
+ stream = Stream.new('Stream A')
1231
+ dummy = Stream.new('Dummy')
1232
+
1233
+ expect(repository.count(specification.result)).to eq(0)
1234
+ (1..3).each do
1235
+ repository.append_to_stream([SRecord.new(event_type: Type1.to_s)], stream, version_any)
1236
+ end
1237
+ expect(repository.count(specification.result)).to eq(3)
1238
+ event_id = SecureRandom.uuid
1239
+ repository.append_to_stream([SRecord.new(event_type: Type1.to_s, event_id: event_id)], dummy, version_any)
1240
+ expect(repository.count(specification.result)).to eq(4)
1241
+ expect(repository.count(specification.in_batches.result)).to eq(4)
1242
+ expect(repository.count(specification.in_batches(2).result)).to eq(4)
1243
+
1244
+ expect(repository.count(specification.with_id([event_id]).result)).to eq(1)
1245
+ not_existing_uuid = SecureRandom.uuid
1246
+ expect(repository.count(specification.with_id([not_existing_uuid]).result)).to eq(0)
1247
+
1248
+ expect(repository.count(specification.stream(stream.name).result)).to eq(3)
1249
+ expect(repository.count(specification.stream('Dummy').result)).to eq(1)
1250
+ expect(repository.count(specification.stream('not-existing-stream').result)).to eq(0)
1251
+
1252
+ repository.append_to_stream([SRecord.new(event_type: Type1.to_s)], dummy, version_any)
1253
+ expect(repository.count(specification.from(:head).result)).to eq(5)
1254
+ expect(repository.count(specification.from(event_id).result)).to eq(1)
1255
+ expect(repository.count(specification.stream("Dummy").from(:head).result)).to eq(2)
1256
+ expect(repository.count(specification.stream("Dummy").from(event_id).result)).to eq(1)
1257
+
1258
+ expect(repository.count(specification.limit(100).result)).to eq(5)
1259
+ expect(repository.count(specification.limit(2).result)).to eq(2)
1260
+
1261
+ repository.append_to_stream([SRecord.new(event_type: Type2.to_s)], dummy, version_any)
1262
+ repository.append_to_stream([SRecord.new(event_type: Type3.to_s)], dummy, version_any)
1263
+ repository.append_to_stream([SRecord.new(event_type: Type3.to_s)], dummy, version_any)
1264
+ expect(repository.count(specification.of_type([Type1]).result)).to eq(5)
1265
+ expect(repository.count(specification.of_type([Type2]).result)).to eq(1)
1266
+ expect(repository.count(specification.of_type([Type3]).result)).to eq(2)
1267
+ expect(repository.count(specification.stream("Dummy").of_type([Type3]).result)).to eq(2)
1268
+ expect(repository.count(specification.stream(stream.name).of_type([Type3]).result)).to eq(0)
1269
+ end
1229
1270
  end
1230
1271
  end
@@ -91,6 +91,14 @@ module RubyEventStore
91
91
  end
92
92
  end
93
93
 
94
+ # Calculates the size of result set based on the specification build up to this point.
95
+ # {http://railseventstore.org/docs/read/ Find out more}.
96
+ #
97
+ # @return [Integer] Number of events to read
98
+ def count
99
+ reader.count(result)
100
+ end
101
+
94
102
  # Executes the query based on the specification built up to this point.
95
103
  # Returns array of domain events.
96
104
  # {http://railseventstore.org/docs/read/ Find out more}.
@@ -23,6 +23,12 @@ module RubyEventStore
23
23
  end
24
24
  end
25
25
 
26
+ # @api private
27
+ # @private
28
+ def count(specification_result)
29
+ repository.count(specification_result)
30
+ end
31
+
26
32
  # @api private
27
33
  # @private
28
34
  def has_event?(event_id)
@@ -0,0 +1,25 @@
1
+ module RubyEventStore
2
+ class TransformKeys
3
+ def self.stringify(data)
4
+ transform(data) {|k| k.to_s}
5
+ end
6
+
7
+ def self.symbolize(data)
8
+ transform(data) {|k| k.to_sym}
9
+ end
10
+
11
+ private
12
+ def self.transform(data, &block)
13
+ data.each_with_object({}) do |(k, v), h|
14
+ h[yield(k)] = case v
15
+ when Hash
16
+ transform(v, &block)
17
+ when Array
18
+ v.map{|i| Hash === i ? transform(i, &block) : i}
19
+ else
20
+ v
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,3 +1,3 @@
1
1
  module RubyEventStore
2
- VERSION = "0.34.0"
2
+ VERSION = "0.35.0"
3
3
  end
@@ -25,15 +25,5 @@ Gem::Specification.new do |spec|
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
26
  spec.require_paths = ['lib']
27
27
 
28
-
29
28
  spec.add_dependency 'concurrent-ruby', '~> 1.0'
30
- spec.add_development_dependency 'bundler', '~> 1.15'
31
- spec.add_development_dependency 'rake', '~> 10.0'
32
- spec.add_development_dependency 'rspec', '~> 3.6'
33
- spec.add_development_dependency 'mutant-rspec', '= 0.8.17'
34
- spec.add_development_dependency 'parser'
35
- spec.add_development_dependency 'unparser'
36
- spec.add_development_dependency 'astrolabe'
37
- spec.add_development_dependency 'google-protobuf', '~> 3.5.1.2'
38
- spec.add_development_dependency 'activesupport', '~> 5.0'
39
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_event_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.34.0
4
+ version: 0.35.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arkency
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-23 00:00:00.000000000 Z
11
+ date: 2018-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -24,132 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '1.15'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '1.15'
41
- - !ruby/object:Gem::Dependency
42
- name: rake
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '10.0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '10.0'
55
- - !ruby/object:Gem::Dependency
56
- name: rspec
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '3.6'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '3.6'
69
- - !ruby/object:Gem::Dependency
70
- name: mutant-rspec
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - '='
74
- - !ruby/object:Gem::Version
75
- version: 0.8.17
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - '='
81
- - !ruby/object:Gem::Version
82
- version: 0.8.17
83
- - !ruby/object:Gem::Dependency
84
- name: parser
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: unparser
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: astrolabe
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: google-protobuf
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: 3.5.1.2
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: 3.5.1.2
139
- - !ruby/object:Gem::Dependency
140
- name: activesupport
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '5.0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: '5.0'
153
27
  description: Implementation of Event Store in Ruby
154
28
  email:
155
29
  - dev@arkency.com
@@ -199,6 +73,7 @@ files:
199
73
  - lib/ruby_event_store/specification_reader.rb
200
74
  - lib/ruby_event_store/specification_result.rb
201
75
  - lib/ruby_event_store/stream.rb
76
+ - lib/ruby_event_store/transform_keys.rb
202
77
  - lib/ruby_event_store/version.rb
203
78
  - ruby_event_store.gemspec
204
79
  homepage: https://railseventstore.org
@@ -225,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
225
100
  version: '0'
226
101
  requirements: []
227
102
  rubyforge_project:
228
- rubygems_version: 2.7.6
103
+ rubygems_version: 3.0.0.beta2
229
104
  signing_key:
230
105
  specification_version: 4
231
106
  summary: Event Store in Ruby