pg_eventstore 1.1.3 → 1.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +4 -3
- data/docs/subscriptions.md +25 -2
- data/lib/pg_eventstore/abstract_command.rb +2 -0
- data/lib/pg_eventstore/callbacks.rb +3 -0
- data/lib/pg_eventstore/client.rb +6 -1
- data/lib/pg_eventstore/config.rb +1 -1
- data/lib/pg_eventstore/connection.rb +9 -1
- data/lib/pg_eventstore/errors.rb +45 -26
- data/lib/pg_eventstore/event.rb +2 -1
- data/lib/pg_eventstore/event_class_resolver.rb +1 -1
- data/lib/pg_eventstore/event_deserializer.rb +8 -2
- data/lib/pg_eventstore/event_serializer.rb +2 -0
- data/lib/pg_eventstore/extensions/callbacks_extension.rb +1 -0
- data/lib/pg_eventstore/extensions/options_extension.rb +3 -1
- data/lib/pg_eventstore/queries/event_queries.rb +12 -4
- data/lib/pg_eventstore/queries/links_resolver.rb +3 -0
- data/lib/pg_eventstore/queries/partition_queries.rb +6 -0
- data/lib/pg_eventstore/queries/transaction_queries.rb +4 -0
- data/lib/pg_eventstore/queries.rb +1 -1
- data/lib/pg_eventstore/query_builders/{events_filtering_query.rb → events_filtering.rb} +3 -0
- data/lib/pg_eventstore/sql_builder.rb +18 -10
- data/lib/pg_eventstore/stream.rb +13 -2
- data/lib/pg_eventstore/subscriptions/basic_runner.rb +2 -0
- data/lib/pg_eventstore/subscriptions/commands_handler.rb +5 -3
- data/lib/pg_eventstore/subscriptions/queries/subscription_command_queries.rb +6 -4
- data/lib/pg_eventstore/subscriptions/queries/subscription_queries.rb +4 -2
- data/lib/pg_eventstore/subscriptions/queries/subscriptions_set_command_queries.rb +6 -4
- data/lib/pg_eventstore/subscriptions/queries/subscriptions_set_queries.rb +3 -0
- data/lib/pg_eventstore/subscriptions/runner_state.rb +1 -0
- data/lib/pg_eventstore/subscriptions/subscription.rb +19 -17
- data/lib/pg_eventstore/subscriptions/subscription_feeder.rb +8 -0
- data/lib/pg_eventstore/subscriptions/subscription_feeder_commands/base.rb +4 -4
- data/lib/pg_eventstore/subscriptions/subscription_handler_performance.rb +2 -1
- data/lib/pg_eventstore/subscriptions/subscription_runner.rb +5 -0
- data/lib/pg_eventstore/subscriptions/subscription_runner_commands/base.rb +4 -4
- data/lib/pg_eventstore/subscriptions/subscriptions_manager.rb +15 -5
- data/lib/pg_eventstore/subscriptions/subscriptions_set.rb +10 -10
- data/lib/pg_eventstore/version.rb +2 -1
- data/lib/pg_eventstore/web/application.rb +6 -6
- data/lib/pg_eventstore/web/paginator/base_collection.rb +15 -1
- data/lib/pg_eventstore/web/paginator/event_types_collection.rb +2 -1
- data/lib/pg_eventstore/web/paginator/events_collection.rb +7 -4
- data/lib/pg_eventstore/web/paginator/helpers.rb +3 -3
- data/lib/pg_eventstore/web/paginator/stream_contexts_collection.rb +2 -1
- data/lib/pg_eventstore/web/paginator/stream_ids_collection.rb +2 -1
- data/lib/pg_eventstore/web/paginator/stream_names_collection.rb +2 -1
- data/lib/pg_eventstore/web/subscriptions/set_collection.rb +2 -0
- data/lib/pg_eventstore/web/subscriptions/subscriptions.rb +2 -0
- data/lib/pg_eventstore/web/subscriptions/subscriptions_set.rb +2 -0
- data/lib/pg_eventstore/web/subscriptions/subscriptions_to_set_association.rb +6 -1
- data/lib/pg_eventstore.rb +6 -1
- data/rbs_collection.lock.yaml +16 -0
- data/rbs_collection.yaml +23 -0
- data/sig/interfaces/callback.rbs +3 -0
- data/sig/interfaces/event_class_resolver.rbs +3 -0
- data/sig/interfaces/event_modifier.rbs +3 -0
- data/sig/interfaces/restart_terminator.rbs +3 -0
- data/sig/interfaces/subscription_handler.rbs +3 -0
- data/sig/pg/basic_type_registry.rbs +21 -0
- data/sig/pg/connection.rbs +407 -0
- data/sig/pg/constants.rbs +153 -0
- data/sig/pg_eventstore/abstract_command.rbs +11 -0
- data/sig/pg_eventstore/callbacks.rbs +21 -0
- data/sig/pg_eventstore/client.rbs +67 -0
- data/sig/pg_eventstore/commands/append.rbs +33 -0
- data/sig/pg_eventstore/commands/event_modifiers/prepare_link_event.rbs +24 -0
- data/sig/pg_eventstore/commands/event_modifiers/prepare_regular_event.rbs +12 -0
- data/sig/pg_eventstore/commands/link_to.rbs +17 -0
- data/sig/pg_eventstore/commands/multiple.rbs +7 -0
- data/sig/pg_eventstore/commands/read.rbs +10 -0
- data/sig/pg_eventstore/commands/regular_stream_read_paginated.rbs +32 -0
- data/sig/pg_eventstore/commands/system_stream_read_paginated.rbs +30 -0
- data/sig/pg_eventstore/config.rbs +51 -0
- data/sig/pg_eventstore/connection.rbs +30 -0
- data/sig/pg_eventstore/errors.rbs +116 -0
- data/sig/pg_eventstore/event.rbs +46 -0
- data/sig/pg_eventstore/event_class_resolver.rbs +6 -0
- data/sig/pg_eventstore/event_deserializer.rbs +20 -0
- data/sig/pg_eventstore/event_serializer.rbs +13 -0
- data/sig/pg_eventstore/extensions/callbacks_extension.rbs +23 -0
- data/sig/pg_eventstore/extensions/options_extension.rbs +37 -0
- data/sig/pg_eventstore/extensions/using_connection_extension.rbs +14 -0
- data/sig/pg_eventstore/middleware.rbs +9 -0
- data/sig/pg_eventstore/pg_connection.rbs +13 -0
- data/sig/pg_eventstore/queries/event_queries.rbs +50 -0
- data/sig/pg_eventstore/queries/links_resolver.rbs +19 -0
- data/sig/pg_eventstore/queries/partition_queries.rbs +74 -0
- data/sig/pg_eventstore/queries/transaction_queries.rbs +21 -0
- data/sig/pg_eventstore/queries.rbs +23 -0
- data/sig/pg_eventstore/query_builders/events_filtering_query.rbs +62 -0
- data/sig/pg_eventstore/sql_builder.rbs +74 -0
- data/sig/pg_eventstore/stream.rbs +40 -0
- data/sig/pg_eventstore/subscriptions/basic_runner.rbs +37 -0
- data/sig/pg_eventstore/subscriptions/command_handlers/subscription_feeder_commands.rbs +16 -0
- data/sig/pg_eventstore/subscriptions/command_handlers/subscription_runners_commands.rbs +18 -0
- data/sig/pg_eventstore/subscriptions/commands_handler.rbs +25 -0
- data/sig/pg_eventstore/subscriptions/events_processor.rbs +34 -0
- data/sig/pg_eventstore/subscriptions/extensions/base_command_extension.rbs +20 -0
- data/sig/pg_eventstore/subscriptions/extensions/command_class_lookup_extension.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/queries/subscription_command_queries.rbs +56 -0
- data/sig/pg_eventstore/subscriptions/queries/subscription_queries.rbs +73 -0
- data/sig/pg_eventstore/subscriptions/queries/subscriptions_set_command_queries.rbs +39 -0
- data/sig/pg_eventstore/subscriptions/queries/subscriptions_set_queries.rbs +36 -0
- data/sig/pg_eventstore/subscriptions/runner_state.rbs +16 -0
- data/sig/pg_eventstore/subscriptions/subscription.rbs +96 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder.rbs +64 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder_commands/base.rbs +45 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder_commands/restore.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder_commands/start_all.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder_commands/stop.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder_commands/stop_all.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder_commands.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_handler_performance.rbs +12 -0
- data/sig/pg_eventstore/subscriptions/subscription_runner.rbs +55 -0
- data/sig/pg_eventstore/subscriptions/subscription_runner_commands/base.rbs +47 -0
- data/sig/pg_eventstore/subscriptions/subscription_runner_commands/reset_position.rbs +11 -0
- data/sig/pg_eventstore/subscriptions/subscription_runner_commands/restore.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_runner_commands/start.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_runner_commands/stop.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_runner_commands.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_runners_feeder.rbs +13 -0
- data/sig/pg_eventstore/subscriptions/subscriptions_manager.rbs +62 -0
- data/sig/pg_eventstore/subscriptions/subscriptions_set.rbs +72 -0
- data/sig/pg_eventstore/utils.rbs +20 -0
- data/sig/pg_eventstore/version.rbs +3 -0
- data/sig/pg_eventstore/web/paginator/base_collection.rbs +51 -0
- data/sig/pg_eventstore/web/paginator/event_types_collection.rbs +15 -0
- data/sig/pg_eventstore/web/paginator/events_collection.rbs +31 -0
- data/sig/pg_eventstore/web/paginator/helpers.rbs +38 -0
- data/sig/pg_eventstore/web/paginator/stream_contexts_collection.rbs +15 -0
- data/sig/pg_eventstore/web/paginator/stream_ids_collection.rbs +15 -0
- data/sig/pg_eventstore/web/paginator/stream_names_collection.rbs +15 -0
- data/sig/pg_eventstore/web/subscriptions/helpers.rbs +48 -0
- data/sig/pg_eventstore/web/subscriptions/set_collection.rbs +18 -0
- data/sig/pg_eventstore/web/subscriptions/subscriptions.rbs +18 -0
- data/sig/pg_eventstore/web/subscriptions/subscriptions_set.rbs +18 -0
- data/sig/pg_eventstore/web/subscriptions/subscriptions_to_set_association.rbs +18 -0
- data/sig/pg_eventstore.rbs +42 -0
- metadata +90 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5fce9f1f61310bfc9c12afdb89b0a6589e9116133255eeb62ac406b24e351b72
|
4
|
+
data.tar.gz: 0a03a441f9e26a040f026fc7fac5d034c81b91d6f0e0bee98646b39a2f809147
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26a0a9b9cf70e32fd73d5f729d5d9654ec23cd90aa57a3bfdf4cae5603f58d56d62a1406df477200390497141e5c4bb89f157c749bd1df680c1b404898428094
|
7
|
+
data.tar.gz: 85aeeffcfc9ddfba2733e7362958a9d1528eb043ae5025c2d8bd055aa708e5c20eb2fef555be711174f3c058235c0f5b97c780b9f68b3a52e92592fe58d8f8c3
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.1.5]
|
4
|
+
- Review the way to handle SubscriptionAlreadyLockedError error. This removes noise when attempting to lock an already locked subscription.
|
5
|
+
|
6
|
+
## [1.1.4]
|
7
|
+
- Add rbs signatures
|
8
|
+
|
3
9
|
## [1.1.3]
|
4
10
|
- Fix issue with assets caching between different gem's versions
|
5
11
|
|
data/README.md
CHANGED
@@ -53,10 +53,11 @@ Documentation chapters:
|
|
53
53
|
|
54
54
|
After checking out the repo, run:
|
55
55
|
- `bundle` to install dependencies
|
56
|
-
- `docker
|
57
|
-
- `bin/setup_db` to create/re-create development and test databases, tables and related objects
|
56
|
+
- `docker compose up` to start dev/test services
|
57
|
+
- `bin/setup_db` to create/re-create development and test databases, tables and related objects
|
58
|
+
- `bundle exec rbs collection install` to install external rbs definitions
|
58
59
|
|
59
|
-
Then, run `
|
60
|
+
Then, run `bin/rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
60
61
|
|
61
62
|
To install this gem onto your local machine, run `bundle exec rake install`.
|
62
63
|
|
data/docs/subscriptions.md
CHANGED
@@ -47,9 +47,23 @@ After you added all necessary subscriptions, it is time to start them:
|
|
47
47
|
|
48
48
|
```ruby
|
49
49
|
subscriptions_manager.start
|
50
|
+
# => PgEventstore::BasicRunner
|
50
51
|
```
|
51
52
|
|
52
|
-
After calling `#start` all subscriptions are locked behind the given
|
53
|
+
After calling `#start` all subscriptions are locked behind the given subscriptions set and can't be locked by any other subscriptions set. This measure is needed to prevent running the same subscription under the same subscription set using different processes/subscription managers. Such situation will lead to a malformed subscription state and will break its position, meaning the same event will be processed several times. In real world the lock attempt may still happen. This can be common scenario when using kubernetes which rolls out new deployment before shutting down old one. In this case `#start` will return `nil`. You can use this behavior to properly handle such cases. Example:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
timeout = 20 # 20 seconds
|
57
|
+
deadline = Time.now + timeout
|
58
|
+
loop do
|
59
|
+
break if subscriptions_manager.start
|
60
|
+
if Time.now > deadline
|
61
|
+
puts "Failed to acquire subscriptions lock within #{timeout} seconds. Exiting now."
|
62
|
+
exit
|
63
|
+
end
|
64
|
+
sleep 2
|
65
|
+
end
|
66
|
+
```
|
53
67
|
|
54
68
|
To "unlock" the subscription you should gracefully stop the subscription manager:
|
55
69
|
|
@@ -86,7 +100,16 @@ subscriptions_manager.subscribe(
|
|
86
100
|
}
|
87
101
|
)
|
88
102
|
subscriptions_manager.force_lock! if ENV['FORCE_LOCK'] == 'true'
|
89
|
-
|
103
|
+
timeout = 20 # 20 seconds
|
104
|
+
deadline = Time.now + timeout
|
105
|
+
loop do
|
106
|
+
break if subscriptions_manager.start
|
107
|
+
if Time.now > deadline
|
108
|
+
puts "Failed to acquire subscriptions lock within #{timeout} seconds. Exiting now."
|
109
|
+
exit
|
110
|
+
end
|
111
|
+
sleep 2
|
112
|
+
end
|
90
113
|
|
91
114
|
Kernel.trap('TERM') do
|
92
115
|
puts "Received TERM signal. Stopping Subscriptions Manager and exiting..."
|
@@ -97,12 +97,14 @@ module PgEventstore
|
|
97
97
|
|
98
98
|
private
|
99
99
|
|
100
|
+
# @return [void]
|
100
101
|
def run_before_callbacks(action, *args, **kwargs)
|
101
102
|
@callbacks[action][:before]&.each do |callback|
|
102
103
|
callback.call(*args, **kwargs)
|
103
104
|
end
|
104
105
|
end
|
105
106
|
|
107
|
+
# @return [Object] the result of the passed block
|
106
108
|
def run_around_callbacks(action, *args, **kwargs, &blk)
|
107
109
|
result = nil
|
108
110
|
stack = [proc { result = yield if block_given? }]
|
@@ -113,6 +115,7 @@ module PgEventstore
|
|
113
115
|
result
|
114
116
|
end
|
115
117
|
|
118
|
+
# @return [void]
|
116
119
|
def run_after_callbacks(action, *args, **kwargs)
|
117
120
|
@callbacks[action][:after]&.each do |callback|
|
118
121
|
callback.call(*args, **kwargs)
|
data/lib/pg_eventstore/client.rb
CHANGED
@@ -7,6 +7,8 @@ require_relative 'queries'
|
|
7
7
|
|
8
8
|
module PgEventstore
|
9
9
|
class Client
|
10
|
+
# @!attribute config
|
11
|
+
# @return [PgEventstore::Config]
|
10
12
|
attr_reader :config
|
11
13
|
private :config
|
12
14
|
|
@@ -111,7 +113,10 @@ module PgEventstore
|
|
111
113
|
call(stream, options: { max_count: config.max_count }.merge(options))
|
112
114
|
end
|
113
115
|
|
114
|
-
# @see {#read} for
|
116
|
+
# @see {#read} for the detailed docs
|
117
|
+
# @param stream [PgEventstore::Stream]
|
118
|
+
# @param options [Hash] request options
|
119
|
+
# @param middlewares [Array, nil]
|
115
120
|
# @return [Enumerator] enumerator will yield PgEventstore::Event
|
116
121
|
def read_paginated(stream, options: {}, middlewares: nil)
|
117
122
|
cmd_class = stream.system? ? Commands::SystemStreamReadPaginated : Commands::RegularStreamReadPaginated
|
data/lib/pg_eventstore/config.rb
CHANGED
@@ -30,7 +30,7 @@ module PgEventstore
|
|
30
30
|
# @return [Integer] Time in seconds to wait for the connection in pool to be released
|
31
31
|
option(:connection_pool_timeout) { 5 }
|
32
32
|
# @!attribute subscription_pull_interval
|
33
|
-
# @return [Float] How often Subscription should pull new events, seconds
|
33
|
+
# @return [Float, Integer] How often Subscription should pull new events, seconds
|
34
34
|
option(:subscription_pull_interval) { 1.0 }
|
35
35
|
# @!attribute subscription_max_retries
|
36
36
|
# @return [Integer] max number of retries of failed Subscription
|
@@ -38,7 +38,15 @@ module PgEventstore
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
|
41
|
+
# @!attribute uri
|
42
|
+
# @return [String]
|
43
|
+
attr_reader :uri
|
44
|
+
# @!attribute pool_size
|
45
|
+
# @return [Integer]
|
46
|
+
attr_reader :pool_size
|
47
|
+
# @!attribute pool_timeout
|
48
|
+
# @return [Integer]
|
49
|
+
attr_reader :pool_timeout
|
42
50
|
private :uri, :pool_size, :pool_timeout
|
43
51
|
|
44
52
|
# @param uri [String] PostgreSQL connection URI.
|
data/lib/pg_eventstore/errors.rb
CHANGED
@@ -22,6 +22,8 @@ module PgEventstore
|
|
22
22
|
end
|
23
23
|
|
24
24
|
class StreamNotFoundError < Error
|
25
|
+
# @!attribute stream
|
26
|
+
# @return [PgEventstore::Stream]
|
25
27
|
attr_reader :stream
|
26
28
|
|
27
29
|
# @param stream [PgEventstore::Stream]
|
@@ -32,6 +34,8 @@ module PgEventstore
|
|
32
34
|
end
|
33
35
|
|
34
36
|
class SystemStreamError < Error
|
37
|
+
# @!attribute stream
|
38
|
+
# @return [PgEventstore::Stream]
|
35
39
|
attr_reader :stream
|
36
40
|
|
37
41
|
# @param stream [PgEventstore::Stream]
|
@@ -42,7 +46,15 @@ module PgEventstore
|
|
42
46
|
end
|
43
47
|
|
44
48
|
class WrongExpectedRevisionError < Error
|
45
|
-
|
49
|
+
# @!attribute stream
|
50
|
+
# @return [PgEventstore::Stream]
|
51
|
+
attr_reader :stream
|
52
|
+
# @!attribute revision
|
53
|
+
# @return [Integer]
|
54
|
+
attr_reader :revision
|
55
|
+
# @!attribute expected_revision
|
56
|
+
# @return [Integer, Symbol]
|
57
|
+
attr_reader :expected_revision
|
46
58
|
|
47
59
|
# @param revision [Integer]
|
48
60
|
# @param expected_revision [Integer, Symbol]
|
@@ -96,29 +108,13 @@ module PgEventstore
|
|
96
108
|
end
|
97
109
|
end
|
98
110
|
|
99
|
-
class StreamDeletionError < Error
|
100
|
-
attr_reader :stream_name, :details
|
101
|
-
|
102
|
-
# @param stream_name [String]
|
103
|
-
# @param details [String]
|
104
|
-
def initialize(stream_name, details:)
|
105
|
-
@stream_name = stream_name
|
106
|
-
@details = details
|
107
|
-
super(user_friendly_message)
|
108
|
-
end
|
109
|
-
|
110
|
-
# @return [String]
|
111
|
-
def user_friendly_message
|
112
|
-
<<~TEXT.strip
|
113
|
-
Could not delete #{stream_name.inspect} stream. It seems that a stream with that \
|
114
|
-
name does not exist, has already been deleted or its state does not match the \
|
115
|
-
provided :expected_revision option. Please check #details for more info.
|
116
|
-
TEXT
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
111
|
class RecordNotFound < Error
|
121
|
-
|
112
|
+
# @!attribute table_name
|
113
|
+
# @return [String]
|
114
|
+
attr_reader :table_name
|
115
|
+
# @!attribute id
|
116
|
+
# @return [Integer, String]
|
117
|
+
attr_reader :id
|
122
118
|
|
123
119
|
# @param table_name [String]
|
124
120
|
# @param id [Integer, String]
|
@@ -135,7 +131,15 @@ module PgEventstore
|
|
135
131
|
end
|
136
132
|
|
137
133
|
class SubscriptionAlreadyLockedError < Error
|
138
|
-
|
134
|
+
# @!attribute set
|
135
|
+
# @return [String]
|
136
|
+
attr_reader :set
|
137
|
+
# @!attribute name
|
138
|
+
# @return [String]
|
139
|
+
attr_reader :name
|
140
|
+
# @!attribute lock_id
|
141
|
+
# @return [Integer]
|
142
|
+
attr_reader :lock_id
|
139
143
|
|
140
144
|
# @param set [String] subscriptions set name
|
141
145
|
# @param name [String] subscription's name
|
@@ -157,7 +161,15 @@ module PgEventstore
|
|
157
161
|
end
|
158
162
|
|
159
163
|
class WrongLockIdError < Error
|
160
|
-
|
164
|
+
# @!attribute set
|
165
|
+
# @return [String]
|
166
|
+
attr_reader :set
|
167
|
+
# @!attribute name
|
168
|
+
# @return [String]
|
169
|
+
attr_reader :name
|
170
|
+
# @!attribute lock_id
|
171
|
+
# @return [Integer]
|
172
|
+
attr_reader :lock_id
|
161
173
|
|
162
174
|
# @param set [String] subscriptions set name
|
163
175
|
# @param name [String] subscription's name
|
@@ -179,6 +191,8 @@ module PgEventstore
|
|
179
191
|
end
|
180
192
|
|
181
193
|
class NotPersistedEventError < Error
|
194
|
+
# @!attribute event
|
195
|
+
# @return [PgEventstore::Event]
|
182
196
|
attr_reader :event
|
183
197
|
|
184
198
|
# @param event [PgEventstore::Event]
|
@@ -194,7 +208,12 @@ module PgEventstore
|
|
194
208
|
end
|
195
209
|
|
196
210
|
class MissingPartitions < Error
|
197
|
-
|
211
|
+
# @!attribute stream
|
212
|
+
# @return [PgEventstore::Stream]
|
213
|
+
attr_reader :stream
|
214
|
+
# @!attribute event_types
|
215
|
+
# @return [Array<String>]
|
216
|
+
attr_reader :event_types
|
198
217
|
|
199
218
|
# @param stream [PgEventstore::Stream]
|
200
219
|
# @param event_types [Array<String>]
|
data/lib/pg_eventstore/event.rb
CHANGED
@@ -4,6 +4,7 @@ module PgEventstore
|
|
4
4
|
class Event
|
5
5
|
include Extensions::OptionsExtension
|
6
6
|
|
7
|
+
# @return [String] a type of link event
|
7
8
|
LINK_TYPE = '$>'
|
8
9
|
|
9
10
|
# @!attribute id
|
@@ -44,7 +45,7 @@ module PgEventstore
|
|
44
45
|
attribute(:created_at)
|
45
46
|
|
46
47
|
# Implements comparison of `PgEventstore::Event`-s. Two events matches if all of their attributes matches
|
47
|
-
# @param other [Object,
|
48
|
+
# @param other [Object, PgEventstore::Event]
|
48
49
|
# @return [Boolean]
|
49
50
|
def ==(other)
|
50
51
|
return false unless other.is_a?(PgEventstore::Event)
|
@@ -3,7 +3,12 @@
|
|
3
3
|
module PgEventstore
|
4
4
|
# @!visibility private
|
5
5
|
class EventDeserializer
|
6
|
-
|
6
|
+
# @!attribute middlewares
|
7
|
+
# @return [Array<#deserialize, #serialize>]
|
8
|
+
attr_reader :middlewares
|
9
|
+
# @!attribute event_class_resolver
|
10
|
+
# @return [#call]
|
11
|
+
attr_reader :event_class_resolver
|
7
12
|
|
8
13
|
# @param middlewares [Array<Object<#deserialize, #serialize>>]
|
9
14
|
# @param event_class_resolver [#call]
|
@@ -13,6 +18,7 @@ module PgEventstore
|
|
13
18
|
end
|
14
19
|
|
15
20
|
# @param raw_events [Array<Hash>]
|
21
|
+
# @return [Array<PgEventstore::Event>]
|
16
22
|
def deserialize_many(raw_events)
|
17
23
|
raw_events.map(&method(:deserialize))
|
18
24
|
end
|
@@ -20,7 +26,7 @@ module PgEventstore
|
|
20
26
|
# @param attrs [Hash]
|
21
27
|
# @return [PgEventstore::Event]
|
22
28
|
def deserialize(attrs)
|
23
|
-
event = event_class_resolver.call(attrs['type']).new(**attrs.transform_keys(&:to_sym))
|
29
|
+
event = event_class_resolver.call(attrs['type']).new(**attrs.except('link').transform_keys(&:to_sym))
|
24
30
|
middlewares.each do |middleware|
|
25
31
|
middleware.deserialize(event)
|
26
32
|
end
|
@@ -81,7 +81,8 @@ module PgEventstore
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
-
ReadonlyAttributeError
|
84
|
+
class ReadonlyAttributeError < StandardError
|
85
|
+
end
|
85
86
|
|
86
87
|
def self.included(klass)
|
87
88
|
klass.singleton_class.attr_accessor(:options)
|
@@ -122,6 +123,7 @@ module PgEventstore
|
|
122
123
|
private
|
123
124
|
|
124
125
|
# @param opt_name [Symbol]
|
126
|
+
# @return [void]
|
125
127
|
# @raise [PgEventstore::Extensions::OptionsExtension::ReadOnlyError]
|
126
128
|
def readonly_error(opt_name)
|
127
129
|
raise(
|
@@ -3,7 +3,15 @@
|
|
3
3
|
module PgEventstore
|
4
4
|
# @!visibility private
|
5
5
|
class EventQueries
|
6
|
-
|
6
|
+
# @!attribute connection
|
7
|
+
# @return [PgEventstore::Connection]
|
8
|
+
attr_reader :connection
|
9
|
+
# @!attribute serializer
|
10
|
+
# @return [PgEventstore::EventSerializer]
|
11
|
+
attr_reader :serializer
|
12
|
+
# @!attribute deserializer
|
13
|
+
# @return [PgEventstore::EventDeserializer]
|
14
|
+
attr_reader :deserializer
|
7
15
|
private :connection, :serializer, :deserializer
|
8
16
|
|
9
17
|
# @param connection [PgEventstore::Connection]
|
@@ -32,7 +40,7 @@ module PgEventstore
|
|
32
40
|
# Takes an array of potentially persisted events and loads their ids from db. Those ids can be later used to check
|
33
41
|
# whether events are actually existing events.
|
34
42
|
# @param events [Array<PgEventstore::Event>]
|
35
|
-
# @return [Array<
|
43
|
+
# @return [Array<String>]
|
36
44
|
def ids_from_db(events)
|
37
45
|
sql_builder = SQLBuilder.new.from('events').select('id')
|
38
46
|
partition_attrs = events.map { |event| [event.stream&.context, event.stream&.stream_name, event.type] }.uniq
|
@@ -72,7 +80,7 @@ module PgEventstore
|
|
72
80
|
|
73
81
|
# @param stream [PgEventstore::Stream]
|
74
82
|
# @param events [Array<PgEventstore::Event>]
|
75
|
-
# @return [PgEventstore::Event]
|
83
|
+
# @return [Array<PgEventstore::Event>]
|
76
84
|
def insert(stream, events)
|
77
85
|
sql_rows_for_insert, values = prepared_statements(stream, events)
|
78
86
|
columns = %w[id data metadata stream_revision link_id link_partition_id type context stream_name stream_id]
|
@@ -122,7 +130,7 @@ module PgEventstore
|
|
122
130
|
|
123
131
|
# @param stream [PgEventstore::Stream]
|
124
132
|
# @param options [Hash]
|
125
|
-
# @return [PgEventstore::
|
133
|
+
# @return [PgEventstore::EventsFiltering]
|
126
134
|
def events_filtering(stream, options)
|
127
135
|
return QueryBuilders::EventsFiltering.all_stream_filtering(options) if stream.all_stream?
|
128
136
|
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module PgEventstore
|
4
4
|
# @!visibility private
|
5
5
|
class LinksResolver
|
6
|
+
# @!attribute connection
|
7
|
+
# @return [PgEventstore::Connection]
|
6
8
|
attr_reader :connection
|
7
9
|
private :connection
|
8
10
|
|
@@ -46,6 +48,7 @@ module PgEventstore
|
|
46
48
|
end.to_a
|
47
49
|
end
|
48
50
|
|
51
|
+
# @return [PgEventstore::PartitionQueries]
|
49
52
|
def partition_queries
|
50
53
|
PartitionQueries.new(connection)
|
51
54
|
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module PgEventstore
|
4
4
|
# @!visibility private
|
5
5
|
class PartitionQueries
|
6
|
+
# @!attribute connection
|
7
|
+
# @return [PgEventstore::Connection]
|
6
8
|
attr_reader :connection
|
7
9
|
private :connection
|
8
10
|
|
@@ -69,6 +71,7 @@ module PgEventstore
|
|
69
71
|
end
|
70
72
|
|
71
73
|
# @param stream [PgEventstore::Stream]
|
74
|
+
# @param event_type [String]
|
72
75
|
# @param stream_name_partition_name [String]
|
73
76
|
# @return [Hash] partition attributes
|
74
77
|
def create_event_type_partition(stream, event_type, stream_name_partition_name)
|
@@ -185,6 +188,9 @@ module PgEventstore
|
|
185
188
|
"stream_names_#{Digest::MD5.hexdigest("#{stream.context}-#{stream.stream_name}")[0..5]}"
|
186
189
|
end
|
187
190
|
|
191
|
+
# @param stream [PgEventstore::Stream]
|
192
|
+
# @param event_type [String]
|
193
|
+
# @return [String]
|
188
194
|
def event_type_partition_name(stream, event_type)
|
189
195
|
"event_types_#{Digest::MD5.hexdigest("#{stream.context}-#{stream.stream_name}-#{event_type}")[0..5]}"
|
190
196
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module PgEventstore
|
4
4
|
# @!visibility private
|
5
5
|
class TransactionQueries
|
6
|
+
# @return [Hash<Symbol => String>] symbol to transaction isolation level association
|
6
7
|
ISOLATION_LEVELS = {
|
7
8
|
read_committed: 'READ COMMITTED',
|
8
9
|
repeatable_read: 'REPEATABLE READ',
|
@@ -11,6 +12,8 @@ module PgEventstore
|
|
11
12
|
h.default = h[:serializable]
|
12
13
|
end.freeze
|
13
14
|
|
15
|
+
# @!attribute connection
|
16
|
+
# @return [PgEventstore::Connection]
|
14
17
|
attr_reader :connection
|
15
18
|
private :connection
|
16
19
|
|
@@ -57,6 +60,7 @@ module PgEventstore
|
|
57
60
|
retry
|
58
61
|
end
|
59
62
|
|
63
|
+
# @return [PgEventstore::PartitionQueries]
|
60
64
|
def partition_queries
|
61
65
|
PartitionQueries.new(connection)
|
62
66
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'sql_builder'
|
4
|
-
require_relative 'query_builders/
|
4
|
+
require_relative 'query_builders/events_filtering'
|
5
5
|
require_relative 'queries/transaction_queries'
|
6
6
|
require_relative 'queries/event_queries'
|
7
7
|
require_relative 'queries/partition_queries'
|
@@ -4,7 +4,9 @@ module PgEventstore
|
|
4
4
|
module QueryBuilders
|
5
5
|
# @!visibility private
|
6
6
|
class EventsFiltering
|
7
|
+
# @return [Integer]
|
7
8
|
DEFAULT_LIMIT = 1_000
|
9
|
+
# @return [Hash<String => String, Symbol => String>]
|
8
10
|
SQL_DIRECTIONS = {
|
9
11
|
'asc' => 'ASC',
|
10
12
|
'desc' => 'DESC',
|
@@ -15,6 +17,7 @@ module PgEventstore
|
|
15
17
|
}.tap do |directions|
|
16
18
|
directions.default = 'ASC'
|
17
19
|
end.freeze
|
20
|
+
# @return [Array<Symbol>]
|
18
21
|
SUBSCRIPTIONS_OPTIONS = %i[from_position resolve_link_tos filter max_count].freeze
|
19
22
|
|
20
23
|
class << self
|
@@ -19,13 +19,13 @@ module PgEventstore
|
|
19
19
|
end
|
20
20
|
|
21
21
|
# @param sql [String]
|
22
|
-
# @return self
|
22
|
+
# @return [self]
|
23
23
|
def select(sql)
|
24
24
|
@select_values.push(sql)
|
25
25
|
self
|
26
26
|
end
|
27
27
|
|
28
|
-
# @return self
|
28
|
+
# @return [self]
|
29
29
|
def unselect
|
30
30
|
@select_values.clear
|
31
31
|
self
|
@@ -33,7 +33,7 @@ module PgEventstore
|
|
33
33
|
|
34
34
|
# @param sql [String]
|
35
35
|
# @param arguments [Array] positional values
|
36
|
-
# @return self
|
36
|
+
# @return [self]
|
37
37
|
def where(sql, *arguments)
|
38
38
|
@where_values['AND'].push([sql, arguments])
|
39
39
|
self
|
@@ -41,14 +41,14 @@ module PgEventstore
|
|
41
41
|
|
42
42
|
# @param sql [String]
|
43
43
|
# @param arguments [Object] positional values
|
44
|
-
# @return self
|
44
|
+
# @return [self]
|
45
45
|
def where_or(sql, *arguments)
|
46
46
|
@where_values['OR'].push([sql, arguments])
|
47
47
|
self
|
48
48
|
end
|
49
49
|
|
50
50
|
# @param table_name [String]
|
51
|
-
# @return self
|
51
|
+
# @return [self]
|
52
52
|
def from(table_name)
|
53
53
|
@from_value = table_name
|
54
54
|
self
|
@@ -56,38 +56,40 @@ module PgEventstore
|
|
56
56
|
|
57
57
|
# @param sql [String]
|
58
58
|
# @param arguments [Object]
|
59
|
-
# @return self
|
59
|
+
# @return [self]
|
60
60
|
def join(sql, *arguments)
|
61
61
|
@join_values.push([sql, arguments])
|
62
62
|
self
|
63
63
|
end
|
64
64
|
|
65
65
|
# @param sql [String]
|
66
|
-
# @return self
|
66
|
+
# @return [self]
|
67
67
|
def order(sql)
|
68
68
|
@order_values.push(sql)
|
69
69
|
self
|
70
70
|
end
|
71
71
|
|
72
|
+
# @return [self]
|
72
73
|
def remove_order
|
73
74
|
@order_values.clear
|
74
75
|
self
|
75
76
|
end
|
76
77
|
|
77
78
|
# @param limit [Integer]
|
78
|
-
# @return self
|
79
|
+
# @return [self]
|
79
80
|
def limit(limit)
|
80
81
|
@limit_value = limit.to_i
|
81
82
|
self
|
82
83
|
end
|
83
84
|
|
85
|
+
# @return [self]
|
84
86
|
def remove_limit
|
85
87
|
@limit_value = nil
|
86
88
|
self
|
87
89
|
end
|
88
90
|
|
89
91
|
# @param offset [Integer]
|
90
|
-
# @return self
|
92
|
+
# @return [self]
|
91
93
|
def offset(offset)
|
92
94
|
@offset_value = offset.to_i
|
93
95
|
self
|
@@ -101,17 +103,19 @@ module PgEventstore
|
|
101
103
|
end
|
102
104
|
|
103
105
|
# @param sql [String]
|
104
|
-
# @return self
|
106
|
+
# @return [self]
|
105
107
|
def group(sql)
|
106
108
|
@group_values.push(sql)
|
107
109
|
self
|
108
110
|
end
|
109
111
|
|
112
|
+
# @return [self]
|
110
113
|
def remove_group
|
111
114
|
@group_values.clear
|
112
115
|
self
|
113
116
|
end
|
114
117
|
|
118
|
+
# @return [Array<String, Array<Object>>]
|
115
119
|
def to_exec_params
|
116
120
|
@positional_values.clear
|
117
121
|
@positional_values_size = 0
|
@@ -125,10 +129,13 @@ module PgEventstore
|
|
125
129
|
@positional_values
|
126
130
|
end
|
127
131
|
|
132
|
+
# @param val [Integer]
|
133
|
+
# @return [Integer]
|
128
134
|
def positional_values_size=(val)
|
129
135
|
@positional_values_size = val
|
130
136
|
end
|
131
137
|
|
138
|
+
# @return [Array<String, Array<Object>>]
|
132
139
|
def _to_exec_params
|
133
140
|
return [single_query_sql, @positional_values] if @union_values.empty?
|
134
141
|
|
@@ -188,6 +195,7 @@ module PgEventstore
|
|
188
195
|
end
|
189
196
|
|
190
197
|
# Replaces "?" signs in the given string with positional variables and memorize positional values they refer to.
|
198
|
+
# @param sql [String]
|
191
199
|
# @return [String]
|
192
200
|
def extract_positional_args(sql, *arguments)
|
193
201
|
sql.gsub("?").each_with_index do |_, index|
|