ruby_event_store 0.34.0 → 0.35.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: 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