ruby_event_store 0.29.0 → 0.30.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|