ruby_event_store 0.29.0 → 0.30.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 +4 -4
- data/Makefile +8 -3
- data/exe/res-deprecated-read-api-migrator +19 -0
- data/lib/ruby_event_store.rb +1 -0
- data/lib/ruby_event_store/batch_enumerator.rb +25 -0
- data/lib/ruby_event_store/client.rb +58 -59
- data/lib/ruby_event_store/deprecated_read_api_rewriter.rb +67 -0
- data/lib/ruby_event_store/deprecated_read_api_runner.rb +64 -0
- data/lib/ruby_event_store/event.rb +25 -0
- data/lib/ruby_event_store/in_memory_repository.rb +8 -8
- data/lib/ruby_event_store/projection.rb +3 -30
- data/lib/ruby_event_store/spec/event_repository_lint.rb +376 -266
- data/lib/ruby_event_store/specification.rb +34 -9
- data/lib/ruby_event_store/version.rb +1 -1
- data/ruby_event_store.gemspec +3 -0
- metadata +50 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4df1be4d7e983bb77d1c069496cdca690f72d593a0c0d83f9d3d7519d63ed115
|
4
|
+
data.tar.gz: 0d156019cb436a9fb262b680e3e46d007d7c64ec46f1186bae82c5e4344b03c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 490e25c72237a78d241df447ad97d55f2d245d40ea4d3b7665b5c699e5273d3b8257f06d2a0a3a1d8d3bc0940158819f433d72b47460620a5c4ed756fad5d646
|
7
|
+
data.tar.gz: 4355818327a762070c48a8121728c9914b74881187f028c8dc8c440d46c9b51556621b5fb697cdbbd97fc93c3eaff03cafa69fefa6d84f6655023cb053336ae4
|
data/Makefile
CHANGED
@@ -8,9 +8,14 @@ IGNORE = RubyEventStore.const_missing \
|
|
8
8
|
RubyEventStore::Client::Within\#normalize_to_array \
|
9
9
|
RubyEventStore::Client::Within\#add_thread_subscribers \
|
10
10
|
RubyEventStore::Client::Within\#add_thread_global_subscribers \
|
11
|
-
RubyEventStore::
|
12
|
-
RubyEventStore::
|
13
|
-
RubyEventStore::
|
11
|
+
RubyEventStore::Client\#read_all_streams_forward \
|
12
|
+
RubyEventStore::Client\#read_all_streams_backward \
|
13
|
+
RubyEventStore::Client\#read_stream_events_forward \
|
14
|
+
RubyEventStore::Client\#read_stream_events_backward \
|
15
|
+
RubyEventStore::Client\#read_events_forward \
|
16
|
+
RubyEventStore::Client\#read_events_backward \
|
17
|
+
RubyEventStore::DeprecatedReadAPIRunner* \
|
18
|
+
RubyEventStore::DeprecatedReadAPIRewriter*
|
14
19
|
SUBJECT ?= RubyEventStore*
|
15
20
|
|
16
21
|
install: ## Install gem dependencies
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'ruby_event_store/deprecated_read_api_rewriter'
|
5
|
+
require 'ruby_event_store/deprecated_read_api_runner'
|
6
|
+
rescue LoadError
|
7
|
+
warn <<-EOS
|
8
|
+
|
9
|
+
You need following gems in Gemfile in order to use this script:
|
10
|
+
|
11
|
+
gem 'parser'
|
12
|
+
gem 'unparser'
|
13
|
+
gem 'astrolabe'
|
14
|
+
|
15
|
+
EOS
|
16
|
+
exit(2)
|
17
|
+
end
|
18
|
+
|
19
|
+
RubyEventStore::DeprecatedReadAPIRunner.go(ARGV)
|
data/lib/ruby_event_store.rb
CHANGED
@@ -15,4 +15,5 @@ require 'ruby_event_store/serialized_record'
|
|
15
15
|
require 'ruby_event_store/mappers/default'
|
16
16
|
require 'ruby_event_store/mappers/protobuf'
|
17
17
|
require 'ruby_event_store/mappers/null_mapper'
|
18
|
+
require 'ruby_event_store/batch_enumerator'
|
18
19
|
require 'ruby_event_store/version'
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RubyEventStore
|
2
|
+
class BatchEnumerator
|
3
|
+
def initialize(batch_size, total_limit, reader)
|
4
|
+
@batch_size = batch_size
|
5
|
+
@total_limit = total_limit
|
6
|
+
@reader = reader
|
7
|
+
end
|
8
|
+
|
9
|
+
def each
|
10
|
+
return to_enum unless block_given?
|
11
|
+
(0...total_limit).step(batch_size) do |batch_offset|
|
12
|
+
batch_offset = Integer(batch_offset)
|
13
|
+
batch_limit = [batch_size, total_limit - batch_offset].min
|
14
|
+
result = reader.call(batch_offset, batch_limit)
|
15
|
+
|
16
|
+
break if result.empty?
|
17
|
+
yield result
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_accessor :batch_size, :total_limit, :reader
|
24
|
+
end
|
25
|
+
end
|
@@ -45,79 +45,88 @@ module RubyEventStore
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def read_events_forward(stream_name, start: :head, count: page_size)
|
48
|
-
|
48
|
+
warn <<~EOW
|
49
|
+
RubyEventStore::Client#read_events_forward has been deprecated.
|
50
|
+
|
51
|
+
Use following fluent API to receive exact results:
|
52
|
+
client.read.stream(stream_name).limit(count).from(start).each.to_a
|
53
|
+
EOW
|
54
|
+
read.stream(stream_name).limit(count).from(start).each.to_a
|
49
55
|
end
|
50
56
|
|
51
57
|
def read_events_backward(stream_name, start: :head, count: page_size)
|
52
|
-
|
58
|
+
warn <<~EOW
|
59
|
+
RubyEventStore::Client#read_events_backward has been deprecated.
|
60
|
+
|
61
|
+
Use following fluent API to receive exact results:
|
62
|
+
client.read.stream(stream_name).limit(count).from(start).backward.each.to_a
|
63
|
+
EOW
|
64
|
+
read.stream(stream_name).limit(count).from(start).backward.each.to_a
|
53
65
|
end
|
54
66
|
|
55
67
|
def read_stream_events_forward(stream_name)
|
56
|
-
|
68
|
+
warn <<~EOW
|
69
|
+
RubyEventStore::Client#read_stream_events_forward has been deprecated.
|
70
|
+
|
71
|
+
Use following fluent API to receive exact results:
|
72
|
+
client.read.stream(stream_name).each.to_a
|
73
|
+
EOW
|
74
|
+
read.stream(stream_name).each.to_a
|
57
75
|
end
|
58
76
|
|
59
77
|
def read_stream_events_backward(stream_name)
|
60
|
-
|
78
|
+
warn <<~EOW
|
79
|
+
RubyEventStore::Client#read_stream_events_backward has been deprecated.
|
80
|
+
|
81
|
+
Use following fluent API to receive exact results:
|
82
|
+
client.read.stream(stream_name).backward.each.to_a
|
83
|
+
EOW
|
84
|
+
read.stream(stream_name).backward.each.to_a
|
61
85
|
end
|
62
86
|
|
63
87
|
def read_all_streams_forward(start: :head, count: page_size)
|
64
|
-
|
88
|
+
warn <<~EOW
|
89
|
+
RubyEventStore::Client#read_all_streams_forward has been deprecated.
|
90
|
+
|
91
|
+
Use following fluent API to receive exact results:
|
92
|
+
client.read.limit(count).from(start).each.to_a
|
93
|
+
EOW
|
94
|
+
read.limit(count).from(start).each.to_a
|
65
95
|
end
|
66
96
|
|
67
97
|
def read_all_streams_backward(start: :head, count: page_size)
|
68
|
-
|
98
|
+
warn <<~EOW
|
99
|
+
RubyEventStore::Client#read_all_streams_backward has been deprecated.
|
100
|
+
|
101
|
+
Use following fluent API to receive exact results:
|
102
|
+
client.read.limit(count).from(start).backward.each.to_a
|
103
|
+
EOW
|
104
|
+
read.limit(count).from(start).backward.each.to_a
|
69
105
|
end
|
70
106
|
|
71
107
|
def read_event(event_id)
|
72
108
|
deserialize_event(repository.read_event(event_id))
|
73
109
|
end
|
74
110
|
|
75
|
-
|
76
|
-
|
77
|
-
# OLD:
|
78
|
-
# subscribe(subscriber, event_types, &within)
|
79
|
-
# subscribe(subscriber, event_types)
|
80
|
-
# NEW:
|
81
|
-
# subscribe(subscriber, to:)
|
82
|
-
# subscribe(to:, &subscriber)
|
83
|
-
def subscribe(subscriber = nil, event_types = nil, to: nil, &proc)
|
84
|
-
if to
|
85
|
-
raise ArgumentError, "subscriber must be first argument or block, cannot be both" if subscriber && proc
|
86
|
-
raise SubscriberNotExist, "subscriber must be first argument or block" unless subscriber || proc
|
87
|
-
raise ArgumentError, "list of event types must be second argument or named argument to: , it cannot be both" if event_types
|
88
|
-
subscriber ||= proc
|
89
|
-
event_broker.add_subscriber(subscriber, to)
|
90
|
-
else
|
91
|
-
if proc
|
92
|
-
warn(DEPRECATED_WITHIN)
|
93
|
-
within(&proc).subscribe(subscriber, to: event_types).call
|
94
|
-
-> {}
|
95
|
-
else
|
96
|
-
warn(DEPRECATED_TO)
|
97
|
-
subscribe(subscriber, to: event_types)
|
98
|
-
end
|
99
|
-
end
|
111
|
+
def read
|
112
|
+
Specification.new(repository, mapper)
|
100
113
|
end
|
101
114
|
|
102
|
-
|
103
|
-
#
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
115
|
+
# subscribe(subscriber, to:)
|
116
|
+
# subscribe(to:, &subscriber)
|
117
|
+
def subscribe(subscriber = nil, to:, &proc)
|
118
|
+
raise ArgumentError, "subscriber must be first argument or block, cannot be both" if subscriber && proc
|
119
|
+
raise SubscriberNotExist, "subscriber must be first argument or block" unless subscriber || proc
|
120
|
+
subscriber ||= proc
|
121
|
+
event_broker.add_subscriber(subscriber, to)
|
122
|
+
end
|
123
|
+
|
124
|
+
# subscribe_to_all_events(subscriber)
|
125
|
+
# subscribe_to_all_events(&subscriber)
|
109
126
|
def subscribe_to_all_events(subscriber = nil, &proc)
|
110
|
-
if subscriber
|
111
|
-
|
112
|
-
|
113
|
-
within(&proc).subscribe_to_all_events(subscriber).call
|
114
|
-
-> {}
|
115
|
-
else
|
116
|
-
event_broker.add_global_subscriber(subscriber)
|
117
|
-
end
|
118
|
-
else
|
119
|
-
event_broker.add_global_subscriber(proc)
|
120
|
-
end
|
127
|
+
raise ArgumentError, "subscriber must be first argument or block, cannot be both" if subscriber && proc
|
128
|
+
raise SubscriberNotExist, "subscriber must be first argument or block" unless subscriber || proc
|
129
|
+
event_broker.add_global_subscriber(subscriber || proc)
|
121
130
|
end
|
122
131
|
|
123
132
|
class Within
|
@@ -188,20 +197,10 @@ module RubyEventStore
|
|
188
197
|
end
|
189
198
|
end
|
190
199
|
|
191
|
-
def deserialized_events(serialized_events)
|
192
|
-
serialized_events.map do |sev|
|
193
|
-
deserialize_event(sev)
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
200
|
def deserialize_event(sev)
|
198
201
|
mapper.serialized_record_to_event(sev)
|
199
202
|
end
|
200
203
|
|
201
|
-
def read
|
202
|
-
Specification.new(repository)
|
203
|
-
end
|
204
|
-
|
205
204
|
def normalize_to_array(events)
|
206
205
|
return *events
|
207
206
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'parser/current'
|
2
|
+
require 'unparser'
|
3
|
+
require 'ruby_event_store'
|
4
|
+
|
5
|
+
|
6
|
+
module RubyEventStore
|
7
|
+
class DeprecatedReadAPIRewriter < ::Parser::Rewriter
|
8
|
+
def on_send(node)
|
9
|
+
node.each_descendant(:send) { |desc_node| on_send(desc_node) }
|
10
|
+
|
11
|
+
_, method_name, *args = node.children
|
12
|
+
replace_range = node.location.selector
|
13
|
+
replace_range = replace_range.join(node.location.end) if node.location.end
|
14
|
+
|
15
|
+
case method_name
|
16
|
+
when :read_all_streams_backward, :read_events_backward
|
17
|
+
rewrite_api("read.backward", replace_range, **parse_args(args))
|
18
|
+
when :read_stream_events_backward
|
19
|
+
rewrite_api("read.backward", replace_range, count: nil, **parse_args(args))
|
20
|
+
when :read_all_streams_forward, :read_events_forward
|
21
|
+
rewrite_api("read", replace_range, **parse_args(args))
|
22
|
+
when :read_stream_events_forward
|
23
|
+
rewrite_api("read", replace_range, count: nil, **parse_args(args))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def rewrite_api(query, range, start: nil, count: PAGE_SIZE, stream: nil)
|
28
|
+
query << ".stream(#{stream})" if stream
|
29
|
+
query << ".from(#{start})" if start
|
30
|
+
query << ".limit(#{count})" if count
|
31
|
+
|
32
|
+
replace(range, "#{query}.each.to_a")
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_args(args)
|
36
|
+
return {} if args.empty?
|
37
|
+
|
38
|
+
case args.size
|
39
|
+
when 1
|
40
|
+
case args[0].type
|
41
|
+
when :hash
|
42
|
+
stream_name, kwargs = nil, args[0]
|
43
|
+
else
|
44
|
+
stream_name, kwargs = parse_value(args[0]), AST::Node.new(:hash)
|
45
|
+
end
|
46
|
+
else
|
47
|
+
stream_name, kwargs = parse_value(args[0]), args[1]
|
48
|
+
end
|
49
|
+
|
50
|
+
kwargs
|
51
|
+
.children
|
52
|
+
.reduce({stream: stream_name}) do |memo, pair|
|
53
|
+
keyword, value = pair.children
|
54
|
+
memo[parse_keyword(keyword)] = parse_value(value)
|
55
|
+
memo
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def parse_value(node)
|
60
|
+
Unparser.unparse(node)
|
61
|
+
end
|
62
|
+
|
63
|
+
def parse_keyword(node)
|
64
|
+
node.children[0].to_sym
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'parser/runner'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'astrolabe/builder'
|
4
|
+
|
5
|
+
|
6
|
+
module RubyEventStore
|
7
|
+
class DeprecatedReadAPIRunner < Parser::Runner
|
8
|
+
attr_reader :rewriter, :parser_class, :modify
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
super
|
12
|
+
@rewriter = DeprecatedReadAPIRewriter.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def runner_name
|
16
|
+
"res-deprecated-read-api-migrator"
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup_option_parsing(opts)
|
20
|
+
super(opts)
|
21
|
+
|
22
|
+
opts.on '-m', '--modify' do
|
23
|
+
@modify = true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def process(buffer)
|
28
|
+
parser = parser_class.new(Astrolabe::Builder.new)
|
29
|
+
new_source = rewriter.rewrite(buffer, parser.parse(buffer))
|
30
|
+
new_buffer = Parser::Source::Buffer.new(buffer.name + '|after res-deprecated-read-api-migrator')
|
31
|
+
new_buffer.source = new_source
|
32
|
+
|
33
|
+
if !modify
|
34
|
+
old = Tempfile.new('old')
|
35
|
+
old.write(buffer.source + "\n")
|
36
|
+
old.flush
|
37
|
+
|
38
|
+
new = Tempfile.new('new')
|
39
|
+
new.write(new_source + "\n")
|
40
|
+
new.flush
|
41
|
+
|
42
|
+
IO.popen("diff -u #{old.path} #{new.path}") do |io|
|
43
|
+
$stderr.write(
|
44
|
+
io.read
|
45
|
+
.sub(/^---.*/, "--- #{buffer.name}")
|
46
|
+
.sub(/^\+\+\+.*/, "+++ #{new_buffer.name}")
|
47
|
+
)
|
48
|
+
end
|
49
|
+
exit(1)
|
50
|
+
end
|
51
|
+
|
52
|
+
if File.exist?(buffer.name)
|
53
|
+
File.open(buffer.name, 'w') do |file|
|
54
|
+
file.write(new_source)
|
55
|
+
end
|
56
|
+
else
|
57
|
+
if input_size > 1
|
58
|
+
puts "Rewritten content of #{buffer.name}:"
|
59
|
+
end
|
60
|
+
puts new_source
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -9,6 +9,10 @@ module RubyEventStore
|
|
9
9
|
end
|
10
10
|
attr_reader :event_id, :metadata, :data
|
11
11
|
|
12
|
+
def message_id
|
13
|
+
event_id
|
14
|
+
end
|
15
|
+
|
12
16
|
def type
|
13
17
|
self.class.name
|
14
18
|
end
|
@@ -43,6 +47,27 @@ module RubyEventStore
|
|
43
47
|
].hash ^ BIG_VALUE
|
44
48
|
end
|
45
49
|
|
50
|
+
def correlation_id
|
51
|
+
metadata[:correlation_id]
|
52
|
+
end
|
53
|
+
|
54
|
+
def correlation_id=(val)
|
55
|
+
metadata[:correlation_id] = val
|
56
|
+
end
|
57
|
+
|
58
|
+
def causation_id
|
59
|
+
metadata[:causation_id]
|
60
|
+
end
|
61
|
+
|
62
|
+
def causation_id=(val)
|
63
|
+
metadata[:causation_id]= val
|
64
|
+
end
|
65
|
+
|
66
|
+
def correlate_with(other_message)
|
67
|
+
self.correlation_id = other_message.correlation_id || other_message.message_id
|
68
|
+
self.causation_id = other_message.message_id
|
69
|
+
end
|
70
|
+
|
46
71
|
alias_method :eql?, :==
|
47
72
|
end
|
48
73
|
end
|
@@ -38,8 +38,14 @@ module RubyEventStore
|
|
38
38
|
def read(spec)
|
39
39
|
events = spec.global_stream? ? global : stream_of(spec.stream_name)
|
40
40
|
events = events.reverse if spec.backward?
|
41
|
-
events =
|
42
|
-
events.
|
41
|
+
events = events.drop(index_of(events, spec.start) + 1) unless spec.head?
|
42
|
+
events = events[0...spec.count] if spec.limit?
|
43
|
+
if spec.batched?
|
44
|
+
batch_reader = ->(offset, limit) { events.drop(offset).take(limit) }
|
45
|
+
BatchEnumerator.new(spec.batch_size, events.size, batch_reader).each
|
46
|
+
else
|
47
|
+
events.each
|
48
|
+
end
|
43
49
|
end
|
44
50
|
|
45
51
|
private
|
@@ -94,12 +100,6 @@ module RubyEventStore
|
|
94
100
|
self
|
95
101
|
end
|
96
102
|
|
97
|
-
def read_batch(source, start_event_id, count)
|
98
|
-
return source[0..count - 1] if start_event_id.equal?(:head)
|
99
|
-
start_index = index_of(source, start_event_id)
|
100
|
-
source[start_index + 1..start_index + count]
|
101
|
-
end
|
102
|
-
|
103
103
|
def index_of(source, event_id)
|
104
104
|
source.index {|item| item.event_id.eql?(event_id)}
|
105
105
|
end
|