pg_eventstore 1.11.0 → 1.12.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/CHANGELOG.md +4 -0
- data/docs/reading_events.md +98 -0
- data/lib/pg_eventstore/client.rb +22 -4
- data/lib/pg_eventstore/commands/all_stream_read_grouped.rb +69 -0
- data/lib/pg_eventstore/commands/regular_stream_read_grouped.rb +31 -0
- data/lib/pg_eventstore/commands.rb +2 -0
- data/lib/pg_eventstore/partition.rb +23 -0
- data/lib/pg_eventstore/queries/event_queries.rb +18 -0
- data/lib/pg_eventstore/queries/partition_queries.rb +21 -0
- data/lib/pg_eventstore/queries.rb +2 -0
- data/lib/pg_eventstore/query_builders/basic_filtering.rb +27 -0
- data/lib/pg_eventstore/query_builders/events_filtering.rb +47 -31
- data/lib/pg_eventstore/query_builders/partitions_filtering.rb +83 -0
- data/lib/pg_eventstore/sql_builder.rb +10 -0
- data/lib/pg_eventstore/subscriptions/queries/subscription_queries.rb +1 -9
- data/lib/pg_eventstore/utils.rb +5 -4
- data/lib/pg_eventstore/version.rb +1 -1
- data/lib/pg_eventstore/web/application.rb +4 -3
- data/lib/pg_eventstore.rb +1 -0
- data/sig/pg_eventstore/client.rbs +2 -0
- data/sig/pg_eventstore/commands/all_stream_read_grouped.rbs +16 -0
- data/sig/pg_eventstore/commands/regular_stream_read_grouped.rbs +8 -0
- data/sig/pg_eventstore/partition.rbs +15 -0
- data/sig/pg_eventstore/queries/event_queries.rbs +2 -0
- data/sig/pg_eventstore/queries/partition_queries.rbs +6 -0
- data/sig/pg_eventstore/query_builders/basic_filtering.rbs +15 -0
- data/sig/pg_eventstore/query_builders/events_filtering_query.rbs +17 -17
- data/sig/pg_eventstore/query_builders/partitions_filtering.rbs +21 -0
- data/sig/pg_eventstore/sql_builder.rbs +1 -1
- metadata +13 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0de14f58d080bcab32005e045530ca7888761e5415d013dbb262746a02806ba
|
4
|
+
data.tar.gz: fee7b7335212796361b5ded87497c7d744ed5ddfd011a47d54cc2b545991b227
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0dbdd04e5778b292177062e5a44ed9ee4c2fc03e98da945a73523036f62ed09cc27ac00d1a5853e99975b82fc798f2f83639bbb2cd4f1745150ff121ca5d7056
|
7
|
+
data.tar.gz: 060f8b1b51cda7be2c472f914dc611fee2db052a2cd773676013b2175e58cf12c3895e8b631a0d79443804f3a733ca25d7012fac6519551308c890df065457d5
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.12.0]
|
4
|
+
|
5
|
+
- Introduce `#read_grouped` API method that allows to group events by type
|
6
|
+
|
3
7
|
## [1.11.0]
|
4
8
|
|
5
9
|
- Add a global position that caused an error to the subscription's error JSON info. This will help you understand what event caused your subscription to fail.
|
data/docs/reading_events.md
CHANGED
@@ -230,3 +230,101 @@ PgEventstore.client.read_paginated(projection_stream, options: { resolve_link_to
|
|
230
230
|
end
|
231
231
|
end
|
232
232
|
```
|
233
|
+
|
234
|
+
## Grouping events by type
|
235
|
+
|
236
|
+
`pg_eventstore` implements an ability to group events by type when reading from a stream. Example:
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
stream = PgEventstore::Stream.new(context: 'FooCtx', stream_name: 'Foo', stream_id: '1')
|
240
|
+
event1 = PgEventstore::Event.new(type: 'Foo', data: { foo: 1 })
|
241
|
+
event2 = PgEventstore::Event.new(type: 'Foo', data: { foo: 2 })
|
242
|
+
event3 = PgEventstore::Event.new(type: 'Bar', data: { bar: 2 })
|
243
|
+
|
244
|
+
PgEventstore.client.append_to_stream(stream, [event1, event2, event3])
|
245
|
+
|
246
|
+
PgEventstore.client.read_grouped(stream) # => returns event1 and event3
|
247
|
+
```
|
248
|
+
|
249
|
+
API is very similar to the API of `#read`, but it ignores `:max_count` options as the result is always returns a set of event types in your stream.
|
250
|
+
|
251
|
+
Reading most recent events:
|
252
|
+
|
253
|
+
```ruby
|
254
|
+
PgEventstore.client.read_grouped(stream, options: { direction: :desc })
|
255
|
+
```
|
256
|
+
|
257
|
+
Filtering the result by stream attributes:
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
PgEventstore.client.read_grouped(
|
261
|
+
PgEventstore::Stream.all_stream,
|
262
|
+
options: { filter: { streams: [{ context: 'FooCtx' }] } }
|
263
|
+
)
|
264
|
+
```
|
265
|
+
|
266
|
+
Filtering the result by event types:
|
267
|
+
|
268
|
+
```ruby
|
269
|
+
PgEventstore.client.read_grouped(
|
270
|
+
PgEventstore::Stream.all_stream,
|
271
|
+
options: { filter: { event_types: ['Foo', 'Bar'] } }
|
272
|
+
)
|
273
|
+
```
|
274
|
+
|
275
|
+
Filtering by stream attributes and event types:
|
276
|
+
|
277
|
+
```ruby
|
278
|
+
PgEventstore.client.read_grouped(
|
279
|
+
PgEventstore::Stream.all_stream,
|
280
|
+
options: { filter: { streams: [{ context: 'FooCtx' }], event_types: ['Foo', 'Bar'] } }
|
281
|
+
)
|
282
|
+
```
|
283
|
+
|
284
|
+
Reading most recent events until the certain stream revision:
|
285
|
+
|
286
|
+
```ruby
|
287
|
+
PgEventstore.client.read_grouped(stream, options: { direction: :desc, from_revision: 1 })
|
288
|
+
```
|
289
|
+
|
290
|
+
Reading the oldest events from the certain stream revision:
|
291
|
+
|
292
|
+
```ruby
|
293
|
+
PgEventstore.client.read_grouped(stream, options: { direction: :asc, from_revision: 1 })
|
294
|
+
```
|
295
|
+
|
296
|
+
Reading most recent events until the certain global position:
|
297
|
+
|
298
|
+
```ruby
|
299
|
+
PgEventstore.client.read_grouped(PgEventstore::Stream.all_stream, options: { direction: :desc, from_position: 5 })
|
300
|
+
```
|
301
|
+
|
302
|
+
Reading the oldest events from the certain global position:
|
303
|
+
|
304
|
+
```ruby
|
305
|
+
PgEventstore.client.read_grouped(PgEventstore::Stream.all_stream, options: { direction: :asc, from_position: 5 })
|
306
|
+
```
|
307
|
+
|
308
|
+
### Event types list lookup
|
309
|
+
|
310
|
+
If you do not provide event types filter - event types list will be determined based on the rest of arguments(a stream argument or a stream filters option).
|
311
|
+
|
312
|
+
### Multiple events of same type in the result
|
313
|
+
|
314
|
+
If same event type appear in different streams(different by `#context` and `#stream_name`) - those events will appear in the result. This is because even though `Event#type` value may be the same - its meaning may have different meaning in different `context`/`stream_name` couple. Example:
|
315
|
+
|
316
|
+
```ruby
|
317
|
+
stream1 = PgEventstore::Stream.new(context: 'FooCtx', stream_name: 'Foo', stream_id: '1')
|
318
|
+
stream2 = PgEventstore::Stream.new(context: 'FooCtx', stream_name: 'Bar', stream_id: '1')
|
319
|
+
|
320
|
+
event1 = PgEventstore::Event.new(type: 'Foo', data: { foo: 1 })
|
321
|
+
event2 = PgEventstore::Event.new(type: 'Foo', data: { foo: 2 })
|
322
|
+
|
323
|
+
PgEventstore.client.append_to_stream(stream1, event1)
|
324
|
+
PgEventstore.client.append_to_stream(stream2, event2)
|
325
|
+
|
326
|
+
PgEventstore.client.read_grouped(
|
327
|
+
PgEventstore::Stream.all_stream,
|
328
|
+
options: { filter: { streams: [{ context: 'FooCtx' }] } }
|
329
|
+
) # => returns both events even though they are of "Foo" type
|
330
|
+
```
|
data/lib/pg_eventstore/client.rb
CHANGED
@@ -55,10 +55,11 @@ module PgEventstore
|
|
55
55
|
# Read events from the specific stream or from "all" stream.
|
56
56
|
# @param stream [PgEventstore::Stream]
|
57
57
|
# @param options [Hash] request options
|
58
|
-
# @option options [String] :direction read direction
|
58
|
+
# @option options [String] :direction read direction. Allowed values are "Forwards", "Backwards", "asc", "desc",
|
59
|
+
# :asc, :desc
|
59
60
|
# @option options [Integer] :from_revision a starting revision number. **Use this option when stream name is a
|
60
61
|
# normal stream name**
|
61
|
-
# @option options [Integer
|
62
|
+
# @option options [Integer] :from_position a starting global position number. **Use this option when reading
|
62
63
|
# from "all" stream**
|
63
64
|
# @option options [Integer] :max_count max number of events to return in one response. Defaults to config.max_count
|
64
65
|
# @option options [Boolean] :resolve_link_tos When using projections to create new events you
|
@@ -94,7 +95,7 @@ module PgEventstore
|
|
94
95
|
# }
|
95
96
|
# )
|
96
97
|
#
|
97
|
-
# # Filtering
|
98
|
+
# # Filtering a mix of context and event type
|
98
99
|
# PgEventstore.client.read(
|
99
100
|
# PgEventstore::Stream.all_stream,
|
100
101
|
# options: { filter: { streams: [{ context: 'User' }], event_types: ['MyAwesomeEvent'] } }
|
@@ -123,6 +124,23 @@ module PgEventstore
|
|
123
124
|
call(stream, options: { max_count: config.max_count }.merge(options))
|
124
125
|
end
|
125
126
|
|
127
|
+
# Takes a stream, determines a list of even types in it and returns most recent(or very first - depending on
|
128
|
+
# :direction option) events, one of each type. If :event_types filter is provided - uses it instead of automatic
|
129
|
+
# event types lookup logic. The result size is almost always less than or equal to event types list size, so passing
|
130
|
+
# :max_count option does not make any effect. In case if event of same type appears in different context/stream
|
131
|
+
# name - it will be counted as a different event, thus, may appear several times in the result.
|
132
|
+
# @see {#read} for the detailed docs
|
133
|
+
# @param stream [PgEventstore::Stream]
|
134
|
+
# @param options [Hash] request options
|
135
|
+
# @param middlewares [Array, nil]
|
136
|
+
# @return [Array<PgEventstore::Event>]
|
137
|
+
def read_grouped(stream, options: {}, middlewares: nil)
|
138
|
+
cmd_class = stream.all_stream? ? Commands::AllStreamReadGrouped : Commands::RegularStreamReadGrouped
|
139
|
+
cmd_class.
|
140
|
+
new(Queries.new(partitions: partition_queries, events: event_queries(middlewares(middlewares)))).
|
141
|
+
call(stream, options: options)
|
142
|
+
end
|
143
|
+
|
126
144
|
# Links event from one stream into another stream. You can later access it by providing :resolve_link_tos option
|
127
145
|
# when reading from a stream. Only existing events can be linked.
|
128
146
|
# @param stream [PgEventstore::Stream]
|
@@ -149,7 +167,7 @@ module PgEventstore
|
|
149
167
|
private
|
150
168
|
|
151
169
|
# @param middlewares [Array, nil]
|
152
|
-
# @return [Array<
|
170
|
+
# @return [Array<PgEventstore::Middleware>]
|
153
171
|
def middlewares(middlewares = nil)
|
154
172
|
return config.middlewares.values unless middlewares
|
155
173
|
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PgEventstore
|
4
|
+
module Commands
|
5
|
+
# @!visibility private
|
6
|
+
class AllStreamReadGrouped < AbstractCommand
|
7
|
+
# @param stream [PgEventstore::Stream]
|
8
|
+
# @param options [Hash] request options
|
9
|
+
# @option options [String] :direction read direction
|
10
|
+
# @option options [Integer, Symbol] :from_position. **Use this option when reading from "all" stream**
|
11
|
+
# @option options [Boolean] :resolve_link_tos
|
12
|
+
# @option options [Hash] :filter provide it to filter events
|
13
|
+
# @return [Array<PgEventstore::Event>]
|
14
|
+
# @raise [PgEventstore::StreamNotFoundError]
|
15
|
+
def call(stream, options: {})
|
16
|
+
event_types = QueryBuilders::PartitionsFiltering.extract_event_types_filter(options)
|
17
|
+
stream_filters = QueryBuilders::PartitionsFiltering.extract_streams_filter(options)
|
18
|
+
stream_ids_grouped = group_stream_ids(options)
|
19
|
+
options_by_event_type =
|
20
|
+
queries.partitions.partitions(stream_filters, event_types).flat_map do |partition|
|
21
|
+
stream_ids = stream_ids_grouped[[partition.context, partition.stream_name]]
|
22
|
+
next build_filter_options_for_streams(partition, stream_ids, options) if stream_ids
|
23
|
+
|
24
|
+
build_filter_options_for_partitions(partition, options)
|
25
|
+
end
|
26
|
+
queries.events.grouped_events(stream, options_by_event_type, **options.slice(:resolve_link_tos))
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# @param options [Hash]
|
32
|
+
# @return [Hash]
|
33
|
+
def group_stream_ids(options)
|
34
|
+
event_stream_filters = QueryBuilders::EventsFiltering.extract_streams_filter(options)
|
35
|
+
event_stream_filters.each_with_object({}) do |attrs, res|
|
36
|
+
next unless attrs[:stream_id]
|
37
|
+
|
38
|
+
res[[attrs[:context], attrs[:stream_name]]] ||= []
|
39
|
+
res[[attrs[:context], attrs[:stream_name]]].push(attrs[:stream_id])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# @param partition [PgEventstore::Partition]
|
44
|
+
# @param stream_ids [Array<String>]
|
45
|
+
# @param options [Hash]
|
46
|
+
# @return [Array<Hash>]
|
47
|
+
def build_filter_options_for_streams(partition, stream_ids, options)
|
48
|
+
stream_ids.map do |stream_id|
|
49
|
+
filter = {
|
50
|
+
streams: [{ context: partition.context, stream_name: partition.stream_name, stream_id: stream_id }],
|
51
|
+
event_types: [partition.event_type]
|
52
|
+
}
|
53
|
+
options.merge(filter: filter, max_count: 1)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# @param partition [PgEventstore::Partition]
|
58
|
+
# @param options [Hash]
|
59
|
+
# @return [Hash]
|
60
|
+
def build_filter_options_for_partitions(partition, options)
|
61
|
+
filter = {
|
62
|
+
streams: [{ context: partition.context, stream_name: partition.stream_name }],
|
63
|
+
event_types: [partition.event_type]
|
64
|
+
}
|
65
|
+
options.merge(filter: filter, max_count: 1)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PgEventstore
|
4
|
+
module Commands
|
5
|
+
# @!visibility private
|
6
|
+
class RegularStreamReadGrouped < AbstractCommand
|
7
|
+
# @param stream [PgEventstore::Stream]
|
8
|
+
# @param options [Hash] request options
|
9
|
+
# @option options [String] :direction read direction
|
10
|
+
# @option options [Integer, Symbol] :from_revision. **Use this option when stream name is a normal stream name**
|
11
|
+
# @option options [Integer, Symbol] :from_position. **Use this option when reading from "all" stream**
|
12
|
+
# @option options [Boolean] :resolve_link_tos
|
13
|
+
# @option options [Hash] :filter provide it to filter events
|
14
|
+
# @return [Array<PgEventstore::Event>]
|
15
|
+
# @raise [PgEventstore::StreamNotFoundError]
|
16
|
+
def call(stream, options: {})
|
17
|
+
queries.events.stream_revision(stream) || raise(StreamNotFoundError, stream)
|
18
|
+
|
19
|
+
event_types = QueryBuilders::PartitionsFiltering.extract_event_types_filter(options)
|
20
|
+
stream_filters = QueryBuilders::PartitionsFiltering.extract_streams_filter(
|
21
|
+
filter: { streams: [{ context: stream.context, stream_name: stream.stream_name }] }
|
22
|
+
)
|
23
|
+
options_by_event_type = queries.partitions.partitions(stream_filters, event_types).map do |partition|
|
24
|
+
filter = { event_types: [partition.event_type] }
|
25
|
+
options.merge(filter: filter, max_count: 1)
|
26
|
+
end
|
27
|
+
queries.events.grouped_events(stream, options_by_event_type, **options.slice(:resolve_link_tos))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -5,6 +5,8 @@ require_relative 'commands/event_modifiers/prepare_link_event'
|
|
5
5
|
require_relative 'commands/event_modifiers/prepare_regular_event'
|
6
6
|
require_relative 'commands/append'
|
7
7
|
require_relative 'commands/read'
|
8
|
+
require_relative 'commands/regular_stream_read_grouped'
|
9
|
+
require_relative 'commands/all_stream_read_grouped'
|
8
10
|
require_relative 'commands/regular_stream_read_paginated'
|
9
11
|
require_relative 'commands/system_stream_read_paginated'
|
10
12
|
require_relative 'commands/multiple'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PgEventstore
|
4
|
+
class Partition
|
5
|
+
include Extensions::OptionsExtension
|
6
|
+
|
7
|
+
# @!attribute id
|
8
|
+
# @return [Integer]
|
9
|
+
option(:id)
|
10
|
+
# @!attribute context
|
11
|
+
# @return [String]
|
12
|
+
option(:context)
|
13
|
+
# @!attribute stream_name
|
14
|
+
# @return [String, nil]
|
15
|
+
option(:stream_name)
|
16
|
+
# @!attribute event_type
|
17
|
+
# @return [String, nil]
|
18
|
+
option(:event_type)
|
19
|
+
# @!attribute table_name
|
20
|
+
# @return [String]
|
21
|
+
option(:table_name)
|
22
|
+
end
|
23
|
+
end
|
@@ -98,6 +98,24 @@ module PgEventstore
|
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
|
+
# @param stream [PgEventstore::Stream]
|
102
|
+
# @param options_by_event_type [Array<Hash>] a set of options per an event type
|
103
|
+
# @param options [Hash]
|
104
|
+
# @option options [Boolean] :resolve_link_tos
|
105
|
+
# @return [Array<PgEventstore::Event>]
|
106
|
+
def grouped_events(stream, options_by_event_type, **options)
|
107
|
+
builders = options_by_event_type.map do |filter|
|
108
|
+
QueryBuilders::EventsFiltering.events_filtering(stream, filter)
|
109
|
+
end
|
110
|
+
final_builder = SQLBuilder.union_builders(builders.map(&:to_sql_builder))
|
111
|
+
|
112
|
+
raw_events = connection.with do |conn|
|
113
|
+
conn.exec_params(*final_builder.to_exec_params)
|
114
|
+
end.to_a
|
115
|
+
raw_events = links_resolver.resolve(raw_events) if options[:resolve_link_tos]
|
116
|
+
deserializer.deserialize_many(raw_events)
|
117
|
+
end
|
118
|
+
|
101
119
|
private
|
102
120
|
|
103
121
|
# @param stream [PgEventstore::Stream]
|
@@ -176,6 +176,19 @@ module PgEventstore
|
|
176
176
|
end.to_a
|
177
177
|
end
|
178
178
|
|
179
|
+
# @param stream_filters [Array<Hash[Symbol, String]>]
|
180
|
+
# @param event_filters [Array<String>]
|
181
|
+
# @return [Array<PgEventstore::Partition>]
|
182
|
+
def partitions(stream_filters, event_filters)
|
183
|
+
partitions_filter = QueryBuilders::PartitionsFiltering.new
|
184
|
+
stream_filters.each { |attrs| partitions_filter.add_stream_attrs(**attrs) }
|
185
|
+
partitions_filter.add_event_types(event_filters)
|
186
|
+
partitions_filter.with_event_types
|
187
|
+
connection.with do |conn|
|
188
|
+
conn.exec_params(*partitions_filter.to_exec_params)
|
189
|
+
end.map(&method(:deserialize))
|
190
|
+
end
|
191
|
+
|
179
192
|
# @param stream [PgEventstore::Stream]
|
180
193
|
# @return [String]
|
181
194
|
def context_partition_name(stream)
|
@@ -194,5 +207,13 @@ module PgEventstore
|
|
194
207
|
def event_type_partition_name(stream, event_type)
|
195
208
|
"event_types_#{Digest::MD5.hexdigest("#{stream.context}-#{stream.stream_name}-#{event_type}")[0..5]}"
|
196
209
|
end
|
210
|
+
|
211
|
+
private
|
212
|
+
|
213
|
+
# @param attrs [Hash]
|
214
|
+
# @return [PgEventstore::Partition]
|
215
|
+
def deserialize(attrs)
|
216
|
+
Partition.new(**attrs.transform_keys(&:to_sym))
|
217
|
+
end
|
197
218
|
end
|
198
219
|
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'sql_builder'
|
4
|
+
require_relative 'query_builders/basic_filtering'
|
4
5
|
require_relative 'query_builders/events_filtering'
|
6
|
+
require_relative 'query_builders/partitions_filtering'
|
5
7
|
require_relative 'queries/transaction_queries'
|
6
8
|
require_relative 'queries/event_queries'
|
7
9
|
require_relative 'queries/partition_queries'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PgEventstore
|
4
|
+
module QueryBuilders
|
5
|
+
# @!visibility private
|
6
|
+
class BasicFiltering
|
7
|
+
def initialize
|
8
|
+
@sql_builder = SQLBuilder.new.select("#{to_table_name}.*").from(to_table_name)
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [String]
|
12
|
+
def to_table_name
|
13
|
+
raise NotImplementedError
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [PgEventstore::SQLBuilder]
|
17
|
+
def to_sql_builder
|
18
|
+
@sql_builder
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Array]
|
22
|
+
def to_exec_params
|
23
|
+
@sql_builder.to_exec_params
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -3,7 +3,11 @@
|
|
3
3
|
module PgEventstore
|
4
4
|
module QueryBuilders
|
5
5
|
# @!visibility private
|
6
|
-
class EventsFiltering
|
6
|
+
class EventsFiltering < BasicFiltering
|
7
|
+
# @return [String]
|
8
|
+
TABLE_NAME = 'events'
|
9
|
+
private_constant :TABLE_NAME
|
10
|
+
|
7
11
|
# @return [Integer]
|
8
12
|
DEFAULT_LIMIT = 1_000
|
9
13
|
# @return [Hash<String => String, Symbol => String>]
|
@@ -26,6 +30,7 @@ module PgEventstore
|
|
26
30
|
# @return [PgEventstore::EventsFiltering]
|
27
31
|
def events_filtering(stream, options)
|
28
32
|
return all_stream_filtering(options) if stream.all_stream?
|
33
|
+
|
29
34
|
if stream.system? && Stream::KNOWN_SYSTEM_STREAMS.include?(stream.context)
|
30
35
|
return system_stream_filtering(stream, options)
|
31
36
|
end
|
@@ -43,11 +48,9 @@ module PgEventstore
|
|
43
48
|
# @return [PgEventstore::QueryBuilders::EventsFiltering]
|
44
49
|
def all_stream_filtering(options)
|
45
50
|
event_filter = new
|
46
|
-
options
|
47
|
-
event_filter.add_event_types(event_types)
|
51
|
+
event_filter.add_event_types(extract_event_types_filter(options))
|
48
52
|
event_filter.add_limit(options[:max_count])
|
49
|
-
options
|
50
|
-
streams&.each { |attrs| event_filter.add_stream_attrs(**attrs) }
|
53
|
+
extract_streams_filter(options).each { |attrs| event_filter.add_stream_attrs(**attrs) }
|
51
54
|
event_filter.add_global_position(options[:from_position], options[:direction])
|
52
55
|
event_filter.add_all_stream_direction(options[:direction])
|
53
56
|
event_filter
|
@@ -58,8 +61,7 @@ module PgEventstore
|
|
58
61
|
# @return [PgEventstore::QueryBuilders::EventsFiltering]
|
59
62
|
def specific_stream_filtering(stream, options)
|
60
63
|
event_filter = new
|
61
|
-
options
|
62
|
-
event_filter.add_event_types(event_types)
|
64
|
+
event_filter.add_event_types(extract_event_types_filter(options))
|
63
65
|
event_filter.add_limit(options[:max_count])
|
64
66
|
event_filter.add_stream_attrs(**stream.to_hash)
|
65
67
|
event_filter.add_revision(options[:from_revision], options[:direction])
|
@@ -75,14 +77,39 @@ module PgEventstore
|
|
75
77
|
event_filter.set_source(stream.context)
|
76
78
|
end
|
77
79
|
end
|
80
|
+
|
81
|
+
# @param options [Hash]
|
82
|
+
# @return [Array<String>]
|
83
|
+
def extract_event_types_filter(options)
|
84
|
+
options in { filter: { event_types: Array => event_types } }
|
85
|
+
event_types&.select! do
|
86
|
+
_1.is_a?(String)
|
87
|
+
end
|
88
|
+
event_types || []
|
89
|
+
end
|
90
|
+
|
91
|
+
# @param options [Hash]
|
92
|
+
# @return [Array<Hash[Symbol, String]>]
|
93
|
+
def extract_streams_filter(options)
|
94
|
+
options in { filter: { streams: Array => streams } }
|
95
|
+
streams = streams&.map do
|
96
|
+
_1 in { context: String | NilClass => context }
|
97
|
+
_1 in { stream_name: String | NilClass => stream_name }
|
98
|
+
_1 in { stream_id: String | NilClass => stream_id }
|
99
|
+
{ context: context, stream_name: stream_name, stream_id: stream_id }
|
100
|
+
end
|
101
|
+
streams || []
|
102
|
+
end
|
78
103
|
end
|
79
104
|
|
80
105
|
def initialize
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
106
|
+
super
|
107
|
+
@sql_builder.limit(DEFAULT_LIMIT)
|
108
|
+
end
|
109
|
+
|
110
|
+
# @return [String]
|
111
|
+
def to_table_name
|
112
|
+
TABLE_NAME
|
86
113
|
end
|
87
114
|
|
88
115
|
# @param context [String, nil]
|
@@ -95,21 +122,20 @@ module PgEventstore
|
|
95
122
|
|
96
123
|
stream_attrs.compact!
|
97
124
|
sql = stream_attrs.map do |attr, _|
|
98
|
-
"
|
125
|
+
"#{to_table_name}.#{attr} = ?"
|
99
126
|
end.join(" AND ")
|
100
127
|
@sql_builder.where_or(sql, *stream_attrs.values)
|
101
128
|
end
|
102
129
|
|
103
|
-
# @param event_types [Array<String
|
130
|
+
# @param event_types [Array<String>]
|
104
131
|
# @return [void]
|
105
132
|
def add_event_types(event_types)
|
106
|
-
return if event_types.nil?
|
107
133
|
return if event_types.empty?
|
108
134
|
|
109
135
|
sql = event_types.size.times.map do
|
110
136
|
"?"
|
111
137
|
end.join(", ")
|
112
|
-
@sql_builder.where("
|
138
|
+
@sql_builder.where("#{to_table_name}.type IN (#{sql})", *event_types)
|
113
139
|
end
|
114
140
|
|
115
141
|
# @param revision [Integer, nil]
|
@@ -118,7 +144,7 @@ module PgEventstore
|
|
118
144
|
def add_revision(revision, direction)
|
119
145
|
return unless revision
|
120
146
|
|
121
|
-
@sql_builder.where("
|
147
|
+
@sql_builder.where("#{to_table_name}.stream_revision #{direction_operator(direction)} ?", revision)
|
122
148
|
end
|
123
149
|
|
124
150
|
# @param position [Integer, nil]
|
@@ -127,19 +153,19 @@ module PgEventstore
|
|
127
153
|
def add_global_position(position, direction)
|
128
154
|
return unless position
|
129
155
|
|
130
|
-
@sql_builder.where("
|
156
|
+
@sql_builder.where("#{to_table_name}.global_position #{direction_operator(direction)} ?", position)
|
131
157
|
end
|
132
158
|
|
133
159
|
# @param direction [String, Symbol, nil]
|
134
160
|
# @return [void]
|
135
161
|
def add_stream_direction(direction)
|
136
|
-
@sql_builder.order("
|
162
|
+
@sql_builder.order("#{to_table_name}.stream_revision #{SQL_DIRECTIONS[direction]}")
|
137
163
|
end
|
138
164
|
|
139
165
|
# @param direction [String, Symbol, nil]
|
140
166
|
# @return [void]
|
141
167
|
def add_all_stream_direction(direction)
|
142
|
-
@sql_builder.order("
|
168
|
+
@sql_builder.order("#{to_table_name}.global_position #{SQL_DIRECTIONS[direction]}")
|
143
169
|
end
|
144
170
|
|
145
171
|
# @param limit [Integer, nil]
|
@@ -150,20 +176,10 @@ module PgEventstore
|
|
150
176
|
@sql_builder.limit(limit)
|
151
177
|
end
|
152
178
|
|
153
|
-
# @return [PgEventstore::SQLBuilder]
|
154
|
-
def to_sql_builder
|
155
|
-
@sql_builder
|
156
|
-
end
|
157
|
-
|
158
|
-
# @return [Array]
|
159
|
-
def to_exec_params
|
160
|
-
@sql_builder.to_exec_params
|
161
|
-
end
|
162
|
-
|
163
179
|
# @param table_name [String] system stream view name
|
164
180
|
# @return [void]
|
165
181
|
def set_source(table_name)
|
166
|
-
@sql_builder.from(%{ "#{PG::Connection.escape(table_name)}"
|
182
|
+
@sql_builder.from(%{ "#{PG::Connection.escape(table_name)}" #{to_table_name} })
|
167
183
|
end
|
168
184
|
|
169
185
|
private
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PgEventstore
|
4
|
+
module QueryBuilders
|
5
|
+
# @!visibility private
|
6
|
+
class PartitionsFiltering < BasicFiltering
|
7
|
+
# @return [String]
|
8
|
+
TABLE_NAME = 'partitions'
|
9
|
+
private_constant :TABLE_NAME
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# @param options [Hash]
|
13
|
+
# @return [Array<String>]
|
14
|
+
def extract_event_types_filter(options)
|
15
|
+
options in { filter: { event_types: Array => event_types } }
|
16
|
+
event_types&.select! do
|
17
|
+
_1.is_a?(String)
|
18
|
+
end
|
19
|
+
event_types || []
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param options [Hash]
|
23
|
+
# @return [Array<Hash[Symbol, String]>]
|
24
|
+
def extract_streams_filter(options)
|
25
|
+
options in { filter: { streams: Array => streams } }
|
26
|
+
streams = streams&.map do
|
27
|
+
_1 in { context: String | NilClass => context }
|
28
|
+
_1 in { stream_name: String | NilClass => stream_name }
|
29
|
+
{ context: context, stream_name: stream_name }
|
30
|
+
end
|
31
|
+
streams || []
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [String]
|
36
|
+
def to_table_name
|
37
|
+
TABLE_NAME
|
38
|
+
end
|
39
|
+
|
40
|
+
# @param context [String, nil]
|
41
|
+
# @param stream_name [String, nil]
|
42
|
+
# @return [void]
|
43
|
+
def add_stream_attrs(context: nil, stream_name: nil)
|
44
|
+
stream_attrs = { context: context, stream_name: stream_name }
|
45
|
+
return unless correct_stream_filter?(stream_attrs)
|
46
|
+
|
47
|
+
stream_attrs.compact!
|
48
|
+
sql = stream_attrs.map do |attr, _|
|
49
|
+
"#{to_table_name}.#{attr} = ?"
|
50
|
+
end.join(" AND ")
|
51
|
+
@sql_builder.where_or(sql, *stream_attrs.values)
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param event_types [Array<String>]
|
55
|
+
# @return [void]
|
56
|
+
def add_event_types(event_types)
|
57
|
+
return if event_types.empty?
|
58
|
+
|
59
|
+
@sql_builder.where("#{to_table_name}.event_type = ANY(?::varchar[])", event_types)
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [void]
|
63
|
+
def with_event_types
|
64
|
+
@sql_builder.where('event_type IS NOT NULL')
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
# @param stream_attrs [Hash]
|
70
|
+
# @return [Boolean]
|
71
|
+
def correct_stream_filter?(stream_attrs)
|
72
|
+
result = (stream_attrs in { context: String, stream_name: String } | { context: String, stream_name: nil })
|
73
|
+
return true if result
|
74
|
+
|
75
|
+
PgEventstore&.logger&.debug(<<~TEXT)
|
76
|
+
Ignoring unsupported stream filter format for grouped read #{stream_attrs.compact.inspect}. \
|
77
|
+
See docs/reading_events.md docs for supported formats.
|
78
|
+
TEXT
|
79
|
+
false
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -4,6 +4,16 @@ module PgEventstore
|
|
4
4
|
# Deadly simple SQL builder
|
5
5
|
# @!visibility private
|
6
6
|
class SQLBuilder
|
7
|
+
class << self
|
8
|
+
# @param builders [Array<PgEventstore::SQLBuilder>]
|
9
|
+
# @return [PgEventstore::SQLBuilder]
|
10
|
+
def union_builders(builders)
|
11
|
+
builders[1..].each_with_object(builders[0]) do |builder, first_builder|
|
12
|
+
first_builder.union(builder)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
7
17
|
def initialize
|
8
18
|
@select_values = []
|
9
19
|
@from_value = nil
|
@@ -127,7 +127,7 @@ module PgEventstore
|
|
127
127
|
def subscriptions_events(query_options)
|
128
128
|
return {} if query_options.empty?
|
129
129
|
|
130
|
-
final_builder = union_builders(query_options.map { |id, opts| query_builder(id, opts) })
|
130
|
+
final_builder = SQLBuilder.union_builders(query_options.map { |id, opts| query_builder(id, opts) })
|
131
131
|
raw_events = connection.with do |conn|
|
132
132
|
conn.exec_params(*final_builder.to_exec_params)
|
133
133
|
end.to_a
|
@@ -177,14 +177,6 @@ module PgEventstore
|
|
177
177
|
builder.select("#{id} as runner_id")
|
178
178
|
end
|
179
179
|
|
180
|
-
# @param builders [Array<PgEventstore::SQLBuilder>]
|
181
|
-
# @return [PgEventstore::SQLBuilder]
|
182
|
-
def union_builders(builders)
|
183
|
-
builders[1..].each_with_object(builders[0]) do |builder, first_builder|
|
184
|
-
first_builder.union(builder)
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
180
|
# @return [PgEventstore::TransactionQueries]
|
189
181
|
def transaction_queries
|
190
182
|
TransactionQueries.new(connection)
|
data/lib/pg_eventstore/utils.rb
CHANGED
@@ -85,7 +85,8 @@ module PgEventstore
|
|
85
85
|
def write_to_file(file_path, content)
|
86
86
|
file = File.open(file_path, "w")
|
87
87
|
file.write(content)
|
88
|
-
|
88
|
+
ensure
|
89
|
+
file&.close
|
89
90
|
end
|
90
91
|
|
91
92
|
# @param file_path [String]
|
@@ -99,10 +100,10 @@ module PgEventstore
|
|
99
100
|
# @return [String, nil]
|
100
101
|
def read_pid(file_path)
|
101
102
|
file = File.open(file_path, "r")
|
102
|
-
file.readline.strip
|
103
|
-
file.close
|
104
|
-
end
|
103
|
+
file.readline.strip
|
105
104
|
rescue Errno::ENOENT
|
105
|
+
ensure
|
106
|
+
file&.close
|
106
107
|
end
|
107
108
|
|
108
109
|
# @param exception [StandardError]
|
@@ -27,7 +27,7 @@ module PgEventstore
|
|
27
27
|
helpers(Paginator::Helpers, Subscriptions::Helpers) do
|
28
28
|
# @return [Array<Hash>, nil]
|
29
29
|
def streams_filter
|
30
|
-
|
30
|
+
streams = QueryBuilders::EventsFiltering.extract_streams_filter(params)
|
31
31
|
streams&.select { _1 in { context: String, stream_name: String, stream_id: String } }&.map do
|
32
32
|
Hash[_1.reject { |_, value| value == '' }].transform_keys(&:to_sym)
|
33
33
|
end&.reject { _1.empty? }
|
@@ -41,8 +41,9 @@ module PgEventstore
|
|
41
41
|
|
42
42
|
# @return [Array<String>, nil]
|
43
43
|
def events_filter
|
44
|
-
|
45
|
-
events
|
44
|
+
event_filters = { filter: { event_types: params.dig(:filter, :events) } }
|
45
|
+
events = QueryBuilders::EventsFiltering.extract_event_types_filter(event_filters)
|
46
|
+
events&.reject { _1 == '' }
|
46
47
|
end
|
47
48
|
|
48
49
|
# @return [Symbol]
|
data/lib/pg_eventstore.rb
CHANGED
@@ -9,6 +9,7 @@ require_relative 'pg_eventstore/extensions/callback_handlers_extension'
|
|
9
9
|
require_relative 'pg_eventstore/extensions/using_connection_extension'
|
10
10
|
require_relative 'pg_eventstore/event_class_resolver'
|
11
11
|
require_relative 'pg_eventstore/config'
|
12
|
+
require_relative 'pg_eventstore/partition'
|
12
13
|
require_relative 'pg_eventstore/event'
|
13
14
|
require_relative 'pg_eventstore/stream'
|
14
15
|
require_relative 'pg_eventstore/commands'
|
@@ -26,6 +26,8 @@ module PgEventstore
|
|
26
26
|
# _@param_ `middlewares` — provide a list of middleware names to override a config's middlewares
|
27
27
|
def read: (PgEventstore::Stream stream, ?options: ::Hash[untyped, untyped], ?middlewares: ::Array[::Symbol]?) -> ::Array[PgEventstore::Event]
|
28
28
|
|
29
|
+
def read_grouped: (Stream stream, ?options: Hash[untyped, untyped], ?middlewares: ::Array[::Symbol]?) -> ::Array[PgEventstore::Event]
|
30
|
+
|
29
31
|
# _@param_ `stream`
|
30
32
|
#
|
31
33
|
# _@param_ `options` — request options
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module PgEventstore
|
2
|
+
module Commands
|
3
|
+
class AllStreamReadGrouped < AbstractCommand
|
4
|
+
|
5
|
+
def call: (Stream stream, ?options: ::Hash[untyped, untyped]) -> Array[Event]
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def build_filter_options_for_partitions: (Partition partition, Hash[untyped, untyped] options) -> Hash[untyped, untyped]
|
10
|
+
|
11
|
+
def build_filter_options_for_streams: (Partition partition, Array[String] stream_ids, Hash[untyped, untyped] options) -> Array[Hash[untyped, untyped]]
|
12
|
+
|
13
|
+
def group_stream_ids: (Hash[untyped, untyped] options) -> Hash[untyped, untyped]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module PgEventstore
|
2
|
+
class Partition
|
3
|
+
include Extensions::OptionsExtension
|
4
|
+
|
5
|
+
attr_accessor id: Integer
|
6
|
+
|
7
|
+
attr_accessor context: String
|
8
|
+
|
9
|
+
attr_accessor stream_name: String?
|
10
|
+
|
11
|
+
attr_accessor event_type: String?
|
12
|
+
|
13
|
+
attr_accessor table_name: String
|
14
|
+
end
|
15
|
+
end
|
@@ -10,6 +10,8 @@ module PgEventstore
|
|
10
10
|
# _@param_ `event`
|
11
11
|
def event_exists?: (PgEventstore::Event event) -> bool
|
12
12
|
|
13
|
+
def grouped_events: (Stream stream, Array[Hash[untyped, untyped]] options_by_event_type, **untyped options)-> Array[Event]
|
14
|
+
|
13
15
|
# _@param_ `events`
|
14
16
|
def ids_from_db: (::Array[PgEventstore::Event] events) -> ::Array[String]
|
15
17
|
|
@@ -39,6 +39,8 @@ module PgEventstore
|
|
39
39
|
# _@return_ — partition attributes
|
40
40
|
def context_partition: (PgEventstore::Stream stream) -> ::Hash[untyped, untyped]?
|
41
41
|
|
42
|
+
def partitions: (Array[Hash[Symbol, String | nil]] stream_filters, Array[String] event_filters)-> Array[Partition]
|
43
|
+
|
42
44
|
# _@param_ `stream`
|
43
45
|
#
|
44
46
|
# _@return_ — partition attributes
|
@@ -70,5 +72,9 @@ module PgEventstore
|
|
70
72
|
|
71
73
|
# Returns the value of attribute connection.
|
72
74
|
attr_accessor connection: PgEventstore::Connection
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def deserialize: (Hash[untyped, untyped] attrs)-> Partition
|
73
79
|
end
|
74
80
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module PgEventstore
|
2
|
+
module QueryBuilders
|
3
|
+
class BasicFiltering
|
4
|
+
@sql_builder: SQLBuilder
|
5
|
+
|
6
|
+
def initialize: -> void
|
7
|
+
|
8
|
+
def to_exec_params: -> [String, Array[untyped]]
|
9
|
+
|
10
|
+
def to_sql_builder: -> SQLBuilder
|
11
|
+
|
12
|
+
def to_table_name: -> String
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,39 +1,37 @@
|
|
1
1
|
module PgEventstore
|
2
2
|
module QueryBuilders
|
3
3
|
# @!visibility private
|
4
|
-
class EventsFiltering
|
4
|
+
class EventsFiltering < BasicFiltering
|
5
5
|
DEFAULT_LIMIT: Integer
|
6
6
|
SQL_DIRECTIONS: Hash[String | Symbol, String]
|
7
7
|
SUBSCRIPTIONS_OPTIONS: ::Array[Symbol]
|
8
8
|
|
9
|
-
|
9
|
+
TABLE_NAME: String
|
10
|
+
|
11
|
+
def self.events_filtering: (Stream stream, ::Hash[untyped, untyped] options) -> EventsFiltering
|
12
|
+
|
13
|
+
def self.extract_event_types_filter: (Hash[untyped, untyped] options) -> Array[String]
|
14
|
+
|
15
|
+
def self.extract_streams_filter: (Hash[untyped, untyped] options) -> Array[Hash[untyped, untyped]]
|
10
16
|
|
11
|
-
def self.events_filtering: (PgEventstore::Stream stream, ::Hash[untyped, untyped] options) -> PgEventstore::QueryBuilders::EventsFiltering
|
12
|
-
|
13
17
|
# _@param_ `options`
|
14
|
-
def self.subscriptions_events_filtering: (::Hash[untyped, untyped] options) ->
|
18
|
+
def self.subscriptions_events_filtering: (::Hash[untyped, untyped] options) -> EventsFiltering
|
15
19
|
|
16
20
|
# _@param_ `options`
|
17
|
-
def self.all_stream_filtering: (::Hash[untyped, untyped] options) ->
|
21
|
+
def self.all_stream_filtering: (::Hash[untyped, untyped] options) -> EventsFiltering
|
18
22
|
|
19
23
|
# _@param_ `stream`
|
20
24
|
#
|
21
25
|
# _@param_ `options`
|
22
|
-
def self.specific_stream_filtering: (
|
26
|
+
def self.specific_stream_filtering: (Stream stream, ::Hash[untyped, untyped] options) -> EventsFiltering
|
23
27
|
|
24
|
-
def self.system_stream_filtering: (
|
28
|
+
def self.system_stream_filtering: (Stream stream, Hash[untyped, untyped] options) -> EventsFiltering
|
25
29
|
|
26
30
|
def initialize: () -> void
|
27
31
|
|
28
|
-
# _@param_ `context`
|
29
|
-
#
|
30
|
-
# _@param_ `stream_name`
|
31
|
-
#
|
32
|
-
# _@param_ `stream_id`
|
33
32
|
def add_stream_attrs: (?context: String?, ?stream_name: String?, ?stream_id: String?) -> void
|
34
33
|
|
35
|
-
|
36
|
-
def add_event_types: (::Array[String]? event_types) -> void
|
34
|
+
def add_event_types: (::Array[String] event_types) -> void
|
37
35
|
|
38
36
|
# _@param_ `revision`
|
39
37
|
#
|
@@ -54,9 +52,11 @@ module PgEventstore
|
|
54
52
|
# _@param_ `limit`
|
55
53
|
def add_limit: (Integer? limit) -> void
|
56
54
|
|
57
|
-
def
|
55
|
+
def set_source: (String table_name)-> void
|
56
|
+
|
57
|
+
def to_sql_builder: () -> SQLBuilder
|
58
58
|
|
59
|
-
def to_exec_params: () ->
|
59
|
+
def to_exec_params: () -> [String, Array[untyped]]
|
60
60
|
|
61
61
|
# _@param_ `stream_attrs`
|
62
62
|
def correct_stream_filter?: (::Hash[untyped, untyped] stream_attrs) -> bool
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module PgEventstore
|
2
|
+
module QueryBuilders
|
3
|
+
class PartitionsFiltering < BasicFiltering
|
4
|
+
TABLE_NAME: String
|
5
|
+
|
6
|
+
def self.extract_event_types_filter: (Hash[untyped, untyped] options) -> Array[String]
|
7
|
+
|
8
|
+
def self.extract_streams_filter: (Hash[untyped, untyped] options) -> Array[Hash[untyped, untyped]]
|
9
|
+
|
10
|
+
def add_event_types: (::Array[String] event_types) -> void
|
11
|
+
|
12
|
+
def add_stream_attrs: (?context: String?, ?stream_name: String?) -> void
|
13
|
+
|
14
|
+
def with_event_types: -> void
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def correct_stream_filter?: (::Hash[untyped, untyped] stream_attrs) -> bool
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_eventstore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Dzyzenko
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: pg
|
@@ -116,6 +115,7 @@ files:
|
|
116
115
|
- lib/pg_eventstore/cli/wait_for_subscriptions_set_shutdown.rb
|
117
116
|
- lib/pg_eventstore/client.rb
|
118
117
|
- lib/pg_eventstore/commands.rb
|
118
|
+
- lib/pg_eventstore/commands/all_stream_read_grouped.rb
|
119
119
|
- lib/pg_eventstore/commands/append.rb
|
120
120
|
- lib/pg_eventstore/commands/delete_event.rb
|
121
121
|
- lib/pg_eventstore/commands/delete_stream.rb
|
@@ -124,6 +124,7 @@ files:
|
|
124
124
|
- lib/pg_eventstore/commands/link_to.rb
|
125
125
|
- lib/pg_eventstore/commands/multiple.rb
|
126
126
|
- lib/pg_eventstore/commands/read.rb
|
127
|
+
- lib/pg_eventstore/commands/regular_stream_read_grouped.rb
|
127
128
|
- lib/pg_eventstore/commands/regular_stream_read_paginated.rb
|
128
129
|
- lib/pg_eventstore/commands/system_stream_read_paginated.rb
|
129
130
|
- lib/pg_eventstore/config.rb
|
@@ -139,6 +140,7 @@ files:
|
|
139
140
|
- lib/pg_eventstore/extensions/using_connection_extension.rb
|
140
141
|
- lib/pg_eventstore/maintenance.rb
|
141
142
|
- lib/pg_eventstore/middleware.rb
|
143
|
+
- lib/pg_eventstore/partition.rb
|
142
144
|
- lib/pg_eventstore/pg_connection.rb
|
143
145
|
- lib/pg_eventstore/queries.rb
|
144
146
|
- lib/pg_eventstore/queries/event_queries.rb
|
@@ -146,7 +148,9 @@ files:
|
|
146
148
|
- lib/pg_eventstore/queries/maintenance_queries.rb
|
147
149
|
- lib/pg_eventstore/queries/partition_queries.rb
|
148
150
|
- lib/pg_eventstore/queries/transaction_queries.rb
|
151
|
+
- lib/pg_eventstore/query_builders/basic_filtering.rb
|
149
152
|
- lib/pg_eventstore/query_builders/events_filtering.rb
|
153
|
+
- lib/pg_eventstore/query_builders/partitions_filtering.rb
|
150
154
|
- lib/pg_eventstore/rspec/has_option_matcher.rb
|
151
155
|
- lib/pg_eventstore/rspec/test_helpers.rb
|
152
156
|
- lib/pg_eventstore/sql_builder.rb
|
@@ -271,6 +275,7 @@ files:
|
|
271
275
|
- sig/pg_eventstore/cli/try_unlock_subscriptions_set.rbs
|
272
276
|
- sig/pg_eventstore/cli/wait_for_subscriptions_set_shutdown.rbs
|
273
277
|
- sig/pg_eventstore/client.rbs
|
278
|
+
- sig/pg_eventstore/commands/all_stream_read_grouped.rbs
|
274
279
|
- sig/pg_eventstore/commands/append.rbs
|
275
280
|
- sig/pg_eventstore/commands/delete_event.rbs
|
276
281
|
- sig/pg_eventstore/commands/delete_stream.rbs
|
@@ -279,6 +284,7 @@ files:
|
|
279
284
|
- sig/pg_eventstore/commands/link_to.rbs
|
280
285
|
- sig/pg_eventstore/commands/multiple.rbs
|
281
286
|
- sig/pg_eventstore/commands/read.rbs
|
287
|
+
- sig/pg_eventstore/commands/regular_stream_read_grouped.rbs
|
282
288
|
- sig/pg_eventstore/commands/regular_stream_read_paginated.rbs
|
283
289
|
- sig/pg_eventstore/commands/system_stream_read_paginated.rbs
|
284
290
|
- sig/pg_eventstore/config.rbs
|
@@ -294,6 +300,7 @@ files:
|
|
294
300
|
- sig/pg_eventstore/extensions/using_connection_extension.rbs
|
295
301
|
- sig/pg_eventstore/maintenance.rbs
|
296
302
|
- sig/pg_eventstore/middleware.rbs
|
303
|
+
- sig/pg_eventstore/partition.rbs
|
297
304
|
- sig/pg_eventstore/pg_connection.rbs
|
298
305
|
- sig/pg_eventstore/queries.rbs
|
299
306
|
- sig/pg_eventstore/queries/event_queries.rbs
|
@@ -301,7 +308,9 @@ files:
|
|
301
308
|
- sig/pg_eventstore/queries/maintenance_queries.rbs
|
302
309
|
- sig/pg_eventstore/queries/partition_queries.rbs
|
303
310
|
- sig/pg_eventstore/queries/transaction_queries.rbs
|
311
|
+
- sig/pg_eventstore/query_builders/basic_filtering.rbs
|
304
312
|
- sig/pg_eventstore/query_builders/events_filtering_query.rbs
|
313
|
+
- sig/pg_eventstore/query_builders/partitions_filtering.rbs
|
305
314
|
- sig/pg_eventstore/sql_builder.rbs
|
306
315
|
- sig/pg_eventstore/stream.rbs
|
307
316
|
- sig/pg_eventstore/subscriptions/basic_runner.rbs
|
@@ -368,7 +377,6 @@ metadata:
|
|
368
377
|
homepage_uri: https://github.com/yousty/pg_eventstore
|
369
378
|
source_code_uri: https://github.com/yousty/pg_eventstore
|
370
379
|
changelog_uri: https://github.com/yousty/pg_eventstore/blob/main/CHANGELOG.md
|
371
|
-
post_install_message:
|
372
380
|
rdoc_options: []
|
373
381
|
require_paths:
|
374
382
|
- lib
|
@@ -383,8 +391,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
383
391
|
- !ruby/object:Gem::Version
|
384
392
|
version: '0'
|
385
393
|
requirements: []
|
386
|
-
rubygems_version: 3.
|
387
|
-
signing_key:
|
394
|
+
rubygems_version: 3.6.7
|
388
395
|
specification_version: 4
|
389
396
|
summary: EventStore implementation using PostgreSQL
|
390
397
|
test_files: []
|