evt-message_store-postgres 1.2.0.0 → 2.3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77c708beeefed6f49a2a8df231fc7d8bb84ef2dd75982dc602cb5b6893662869
4
- data.tar.gz: 3255fa00e94215b04d61fac3054ad4db43e64813c266232cf333e79345d7f49d
3
+ metadata.gz: 8c3e7d86d082e713d0debacaf4eeb24634c60e841ae3cc91f1ceccd09bce6ecc
4
+ data.tar.gz: 1aea92a3b91743c6e4b0b77fc7c18820f390fb65b52afeef6e76f734584f6f7b
5
5
  SHA512:
6
- metadata.gz: 6b1e8f43a95d701db50f9c21964a52acebe8c435b11c91befb6a0e1c1cdf25b8a33f50d0457f1a4af0f34cfd6d426eb2bd918fef8c953af4deabd861a45ee0a4
7
- data.tar.gz: 5e63109d9eb4a60f9c2af6c50ee4adca1929fd224defbe558d47e96c5264ebb884553235cbf5962f9f3d1575fefa9f49ec58d10f4795143ba160a94a9dad67a4
6
+ metadata.gz: 62925f4b042b580ffa05ff79f2e23a71f8db57bb815bc906fe287964095695406ba0c2e5a94ba950b29f51c420d29118484c86b62568db2713f78d590fbddbd1
7
+ data.tar.gz: 07cb98b54f68eec14673b87382a4affb49ea59bfbddc1c2b1f6984aa5ea15c60194e62637dce6774893037580133ed306b83b493d6031b648d8fdbad34235117
@@ -15,7 +15,10 @@ require 'message_store/postgres/put'
15
15
  require 'message_store/postgres/write'
16
16
 
17
17
  require 'message_store/postgres/get'
18
+ require 'message_store/postgres/get/condition'
18
19
  require 'message_store/postgres/get/stream'
19
- require 'message_store/postgres/get/category'
20
20
  require 'message_store/postgres/get/stream/last'
21
+ require 'message_store/postgres/get/category'
22
+ require 'message_store/postgres/get/category/correlation'
23
+ require 'message_store/postgres/get/category/consumer_group'
21
24
  require 'message_store/postgres/read'
@@ -1,25 +1,7 @@
1
1
  module MessageStore
2
2
  module Postgres
3
3
  module Controls
4
- module Category
5
- def self.example(category: nil, randomize_category: nil)
6
- if randomize_category.nil?
7
- if !category.nil?
8
- randomize_category = false
9
- end
10
- end
11
-
12
- randomize_category = true if randomize_category.nil?
13
-
14
- category ||= 'test'
15
-
16
- if randomize_category
17
- category = "#{category}#{SecureRandom.hex(16)}XX"
18
- end
19
-
20
- category
21
- end
22
- end
4
+ Category = MessageStore::Controls::Category
23
5
  end
24
6
  end
25
7
  end
@@ -2,20 +2,21 @@ module MessageStore
2
2
  module Postgres
3
3
  module Controls
4
4
  module Put
5
- def self.call(instances: nil, stream_name: nil, message: nil, category: nil)
5
+ def self.call(instances: nil, stream_name: nil, message_data: nil, message: nil, category: nil)
6
6
  instances ||= 1
7
7
  stream_name ||= StreamName.example(category: category)
8
+ message_data ||= message
8
9
 
9
- message_specified = !message.nil?
10
+ message_specified = !message_data.nil?
10
11
 
11
- message ||= MessageData::Write.example
12
+ message_data ||= MessageData::Write.example
12
13
 
13
14
  position = nil
14
15
  instances.times do
15
- position = MessageStore::Postgres::Put.(message, stream_name)
16
+ position = MessageStore::Postgres::Put.(message_data, stream_name)
16
17
 
17
18
  unless message_specified
18
- message.id = MessageData::Write.id
19
+ message_data.id = MessageData::Write.id
19
20
  end
20
21
  end
21
22
 
@@ -4,14 +4,22 @@ module MessageStore
4
4
  def self.included(cls)
5
5
  cls.class_exec do
6
6
  include MessageStore::Get
7
+
7
8
  prepend Call
8
9
  prepend BatchSize
9
10
 
10
- extend SQLCommand
11
-
12
11
  dependency :session, Session
13
12
 
14
- initializer :stream_name, na(:batch_size), :condition
13
+ abstract :configure
14
+ abstract :stream_name
15
+ abstract :sql_command
16
+ abstract :parameters
17
+ abstract :parameter_values
18
+ abstract :last_position
19
+ abstract :log_text
20
+
21
+ virtual :specialize_error
22
+ virtual :assure
15
23
  end
16
24
  end
17
25
 
@@ -21,40 +29,49 @@ module MessageStore
21
29
  end
22
30
  end
23
31
 
24
- def self.build(stream_name, batch_size: nil, session: nil, condition: nil)
32
+ def self.build(stream_name, **args)
25
33
  cls = specialization(stream_name)
26
34
 
27
- cls.new(stream_name, batch_size, condition).tap do |instance|
35
+ session = args.delete(:session)
36
+
37
+ cls.build(stream_name, **args).tap do |instance|
28
38
  instance.configure(session: session)
29
39
  end
30
40
  end
31
41
 
32
- def self.configure(receiver, stream_name, attr_name: nil, batch_size: nil, condition: nil, session: nil)
42
+ def self.configure(receiver, stream_name, **args)
43
+ attr_name = args.delete(:attr_name)
33
44
  attr_name ||= :get
34
- instance = build(stream_name, batch_size: batch_size, condition: condition, session: session)
35
- receiver.public_send "#{attr_name}=", instance
45
+
46
+ instance = build(stream_name, **args)
47
+ receiver.public_send("#{attr_name}=", instance)
36
48
  end
37
49
 
38
50
  def configure(session: nil)
39
- Session.configure self, session: session
51
+ Session.configure(self, session: session)
40
52
  end
41
53
 
42
- def self.call(stream_name, position: nil, batch_size: nil, condition: nil, session: nil)
43
- instance = build(stream_name, batch_size: batch_size, condition: condition, session: session)
54
+ def self.call(stream_name, **args)
55
+ position = args.delete(:position)
56
+ instance = build(stream_name, **args)
44
57
  instance.(position)
45
58
  end
46
59
 
47
60
  module Call
48
- def call(position)
49
- logger.trace(tag: :get) { "Getting message data (Stream Name: #{stream_name}, Position: #{position.inspect}, Batch Size: #{batch_size.inspect})" }
61
+ def call(position=nil, stream_name: nil)
62
+ position ||= self.class::Defaults.position
63
+
64
+ stream_name ||= self.stream_name
50
65
 
51
- position ||= Defaults.position
66
+ assure
67
+
68
+ logger.trace(tag: :get) { "Getting message data (#{log_text(stream_name, position)})" }
52
69
 
53
70
  result = get_result(stream_name, position)
54
71
 
55
72
  message_data = convert(result)
56
73
 
57
- logger.info(tag: :get) { "Finished getting message data (Count: #{message_data.length}, Stream Name: #{stream_name}, Position: #{position.inspect}, Batch Size: #{batch_size.inspect})" }
74
+ logger.info(tag: :get) { "Finished getting message data (Count: #{message_data.length}, #{log_text(stream_name, position)})" }
58
75
  logger.info(tags: [:data, :message_data]) { message_data.pretty_inspect }
59
76
 
60
77
  message_data
@@ -62,53 +79,60 @@ module MessageStore
62
79
  end
63
80
 
64
81
  def get_result(stream_name, position)
65
- logger.trace(tag: :get) { "Getting result (Stream Name: #{stream_name}, Position: #{position.inspect}, Batch Size: #{batch_size.inspect}, Condition: #{condition || '(none)'})" }
66
-
67
- sql_command = self.class.sql_command(stream_name, position, batch_size, condition)
82
+ logger.trace(tag: :get) { "Getting result (#{log_text(stream_name, position)})" }
68
83
 
69
- cond = Get.constrain_condition(condition)
84
+ parameter_values = parameter_values(stream_name, position)
70
85
 
71
- params = [
72
- stream_name,
73
- position,
74
- batch_size,
75
- cond
76
- ]
77
-
78
- result = session.execute(sql_command, params)
86
+ begin
87
+ result = session.execute(sql_command, parameter_values)
88
+ rescue PG::RaiseException => e
89
+ raise_error(e)
90
+ end
79
91
 
80
- logger.debug(tag: :get) { "Finished getting result (Count: #{result.ntuples}, Stream Name: #{stream_name}, Position: #{position.inspect}, Batch Size: #{batch_size.inspect}, Condition: #{condition || '(none)'})" }
92
+ logger.debug(tag: :get) { "Finished getting result (Count: #{result.ntuples}, #{log_text(stream_name, position)})" }
81
93
 
82
94
  result
83
95
  end
84
96
 
85
- def self.constrain_condition(condition)
86
- return nil if condition.nil?
97
+ def convert(result)
98
+ logger.trace(tag: :get) { "Converting result to message data (Result Count: #{result.ntuples})" }
99
+
100
+ message_data = result.map do |record|
101
+ Get.message_data(record)
102
+ end
103
+
104
+ logger.debug(tag: :get) { "Converted result to message data (Message Data Count: #{message_data.length})" }
87
105
 
88
- "(#{condition})"
106
+ message_data
89
107
  end
90
108
 
91
- module SQLCommand
92
- def sql_command(stream_name, position, batch_size, condition)
93
- parameters = '$1::varchar, $2::bigint, $3::bigint, $4::varchar'
94
- command_text(parameters)
95
- end
109
+ def self.message_data(record)
110
+ record['data'] = Get::Deserialize.data(record['data'])
111
+ record['metadata'] = Get::Deserialize.metadata(record['metadata'])
112
+ record['time'] = Get::Time.utc_coerced(record['time'])
113
+
114
+ MessageData::Read.build(record)
96
115
  end
97
116
 
98
- def convert(result)
99
- logger.trace(tag: :get) { "Converting result to message data (Result Count: #{result.ntuples})" }
117
+ def raise_error(pg_error)
118
+ error_message = Get.error_message(pg_error)
100
119
 
101
- message_data = result.map do |record|
102
- record['data'] = Deserialize.data(record['data'])
103
- record['metadata'] = Deserialize.metadata(record['metadata'])
104
- record['time'] = Time.utc_coerced(record['time'])
120
+ error = Condition.error(error_message)
105
121
 
106
- MessageData::Read.build(record)
122
+ if error.nil?
123
+ error = specialize_error(error_message)
107
124
  end
108
125
 
109
- logger.debug(tag: :get) { "Converted result to message data (Message Data Count: #{message_data.length})" }
126
+ if not error.nil?
127
+ logger.error { error_message }
128
+ raise error
129
+ end
110
130
 
111
- message_data
131
+ raise pg_error
132
+ end
133
+
134
+ def self.error_message(pg_error)
135
+ pg_error.message.gsub('ERROR:', '').strip
112
136
  end
113
137
 
114
138
  def self.specialization(stream_name)
@@ -138,10 +162,6 @@ module MessageStore
138
162
  end
139
163
 
140
164
  module Defaults
141
- def self.position
142
- 0
143
- end
144
-
145
165
  def self.batch_size
146
166
  1000
147
167
  end
@@ -2,15 +2,83 @@ module MessageStore
2
2
  module Postgres
3
3
  module Get
4
4
  class Category
5
+ Error = Class.new(RuntimeError)
6
+
5
7
  include Get
6
8
 
7
- def self.command_text(parameters)
9
+ initializer :category, na(:batch_size), :correlation, :consumer_group_member, :consumer_group_size, :condition
10
+ alias :stream_name :category
11
+
12
+ def self.call(category, position: nil, batch_size: nil, correlation: nil, consumer_group_member: nil, consumer_group_size: nil, condition: nil, session: nil)
13
+ instance = build(category, batch_size: batch_size, correlation: correlation, consumer_group_member: consumer_group_member, consumer_group_size: consumer_group_size, condition: condition, session: session)
14
+ instance.(position)
15
+ end
16
+
17
+ def self.build(category, batch_size: nil, correlation: nil, consumer_group_member: nil, consumer_group_size: nil, condition: nil, session: nil)
18
+ instance = new(category, batch_size, correlation, consumer_group_member, consumer_group_size, condition)
19
+ instance.configure(session: session)
20
+ instance
21
+ end
22
+
23
+ def self.configure(receiver, category, attr_name: nil, batch_size: nil, correlation: nil, consumer_group_member: nil, consumer_group_size: nil, condition: nil, session: nil)
24
+ attr_name ||= :get
25
+ instance = build(category, batch_size: batch_size, correlation: correlation, consumer_group_member: consumer_group_member, consumer_group_size: consumer_group_size, condition: condition, session: session)
26
+ receiver.public_send("#{attr_name}=", instance)
27
+ end
28
+
29
+ def configure(session: nil)
30
+ Session.configure(self, session: session)
31
+ end
32
+
33
+ def sql_command
8
34
  "SELECT * FROM get_category_messages(#{parameters});"
9
35
  end
10
36
 
37
+ def parameters
38
+ '$1::varchar, $2::bigint, $3::bigint, $4::varchar, $5::bigint, $6::bigint, $7::varchar'
39
+ end
40
+
41
+ def parameter_values(category, position)
42
+ [
43
+ category,
44
+ position,
45
+ batch_size,
46
+ correlation,
47
+ consumer_group_member,
48
+ consumer_group_size,
49
+ condition
50
+ ]
51
+ end
52
+
11
53
  def last_position(batch)
12
54
  batch.last.global_position
13
55
  end
56
+
57
+ def specialize_error(error_message)
58
+ error = Correlation.error(error_message)
59
+
60
+ if error.nil?
61
+ error = ConsumerGroup.error(error_message)
62
+ end
63
+
64
+ error
65
+ end
66
+
67
+ def log_text(category, position)
68
+ "Category: #{category}, Position: #{position.inspect}, Batch Size: #{batch_size.inspect}, Correlation: #{correlation.inspect}, Consumer Group Member: #{consumer_group_member.inspect}, Consumer Group Size: #{consumer_group_size.inspect}, Condition: #{condition.inspect})"
69
+ end
70
+
71
+ def assure
72
+ if not MessageStore::StreamName.category?(category)
73
+ raise Error, "Must be a category (Stream Name: #{category})"
74
+ end
75
+ end
76
+
77
+ module Defaults
78
+ def self.position
79
+ 1
80
+ end
81
+ end
14
82
  end
15
83
  end
16
84
  end
@@ -0,0 +1,20 @@
1
+ module MessageStore
2
+ module Postgres
3
+ module Get
4
+ class Category
5
+ module ConsumerGroup
6
+ Error = Class.new(RuntimeError)
7
+
8
+ def self.error(error_message)
9
+ if error_message.start_with?('Consumer group size must not be less than 1') ||
10
+ error_message.start_with?('Consumer group member must be less than the group size') ||
11
+ error_message.start_with?('Consumer group member must not be less than 0') ||
12
+ error_message.start_with?('Consumer group member and size must be specified')
13
+ Error.new(error_message)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ module MessageStore
2
+ module Postgres
3
+ module Get
4
+ class Category
5
+ module Correlation
6
+ Error = Class.new(RuntimeError)
7
+
8
+ def self.error(error_message)
9
+ if error_message.start_with?('Correlation must be a category')
10
+ Error.new(error_message)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ module MessageStore
2
+ module Postgres
3
+ module Get
4
+ module Condition
5
+ Error = Class.new(RuntimeError)
6
+
7
+ def self.error(error_message)
8
+ if error_message.start_with?('Retrieval with SQL condition is not activated')
9
+ Get::Condition::Error.new(error_message)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -2,15 +2,69 @@ module MessageStore
2
2
  module Postgres
3
3
  module Get
4
4
  class Stream
5
+ Error = Class.new(RuntimeError)
6
+
5
7
  include Get
6
8
 
7
- def self.command_text(parameters)
9
+ initializer :stream_name, na(:batch_size), :condition
10
+
11
+ def self.call(stream_name, position: nil, batch_size: nil, condition: nil, session: nil)
12
+ instance = build(stream_name, batch_size: batch_size, condition: condition, session: session)
13
+ instance.(position)
14
+ end
15
+
16
+ def self.build(stream_name, batch_size: nil, condition: nil, session: nil)
17
+ instance = new(stream_name, batch_size, condition)
18
+ instance.configure(session: session)
19
+ instance
20
+ end
21
+
22
+ def self.configure(receiver, stream_name, attr_name: nil, batch_size: nil, condition: nil, session: nil)
23
+ attr_name ||= :get
24
+ instance = build(stream_name, batch_size: batch_size, condition: condition, session: session)
25
+ receiver.public_send("#{attr_name}=", instance)
26
+ end
27
+
28
+ def configure(session: nil)
29
+ Session.configure(self, session: session)
30
+ end
31
+
32
+ def sql_command
8
33
  "SELECT * FROM get_stream_messages(#{parameters});"
9
34
  end
10
35
 
36
+ def parameters
37
+ '$1::varchar, $2::bigint, $3::bigint, $4::varchar'
38
+ end
39
+
40
+ def parameter_values(stream_name, position)
41
+ [
42
+ stream_name,
43
+ position,
44
+ batch_size,
45
+ condition
46
+ ]
47
+ end
48
+
11
49
  def last_position(batch)
12
50
  batch.last.position
13
51
  end
52
+
53
+ def log_text(stream_name, position)
54
+ "Stream Name: #{stream_name}, Position: #{position.inspect}, Batch Size: #{batch_size.inspect}, Correlation: #{correlation.inspect}, Condition: #{condition.inspect})"
55
+ end
56
+
57
+ def assure
58
+ if MessageStore::StreamName.category?(stream_name)
59
+ raise Error, "Must be a stream name (Category: #{stream_name})"
60
+ end
61
+ end
62
+
63
+ module Defaults
64
+ def self.position
65
+ 0
66
+ end
67
+ end
14
68
  end
15
69
  end
16
70
  end
@@ -31,11 +31,11 @@ module MessageStore
31
31
 
32
32
  sql_command = self.class.sql_command(stream_name)
33
33
 
34
- params = [
34
+ parameter_values = [
35
35
  stream_name
36
36
  ]
37
37
 
38
- result = session.execute(sql_command, params)
38
+ result = session.execute(sql_command, parameter_values)
39
39
 
40
40
  logger.debug(tag: :get) { "Finished getting result (Count: #{result.ntuples}, Stream: #{stream_name}" }
41
41
 
@@ -47,40 +47,18 @@ module MessageStore
47
47
  def self.sql_command(stream_name)
48
48
  parameters = '$1::varchar'
49
49
 
50
- "SELECT * FROM get_last_message(#{parameters});"
50
+ "SELECT * FROM get_last_stream_message(#{parameters});"
51
51
  end
52
52
 
53
53
  def convert(record)
54
54
  logger.trace(tag: :get) { "Converting record to message data" }
55
55
 
56
- record['data'] = Deserialize.data(record['data'])
57
- record['metadata'] = Deserialize.metadata(record['metadata'])
58
- record['time'] = Time.utc_coerced(record['time'])
59
-
60
- message_data = MessageData::Read.build(record)
56
+ message_data = Get.message_data(record)
61
57
 
62
58
  logger.debug(tag: :get) { "Converted record to message data" }
63
59
 
64
60
  message_data
65
61
  end
66
-
67
- module Deserialize
68
- def self.data(serialized_data)
69
- return nil if serialized_data.nil?
70
- Transform::Read.(serialized_data, :json, MessageData::Hash)
71
- end
72
-
73
- def self.metadata(serialized_metadata)
74
- return nil if serialized_metadata.nil?
75
- Transform::Read.(serialized_metadata, :json, MessageData::Hash)
76
- end
77
- end
78
-
79
- module Time
80
- def self.utc_coerced(local_time)
81
- Clock::UTC.coerce(local_time)
82
- end
83
- end
84
62
  end
85
63
  end
86
64
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: evt-message_store-postgres
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0.0
4
+ version: 2.3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Eventide Project
8
8
  autorequire:
9
9
  bindir: scripts
10
10
  cert_chain: []
11
- date: 2019-11-01 00:00:00.000000000 Z
11
+ date: 2019-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: evt-message_store
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: evt-message_store-postgres-database
28
+ name: evt-log
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: evt-log
42
+ name: evt-settings
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: evt-settings
56
+ name: message-db
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -137,6 +137,9 @@ files:
137
137
  - lib/message_store/postgres/controls/stream_name.rb
138
138
  - lib/message_store/postgres/get.rb
139
139
  - lib/message_store/postgres/get/category.rb
140
+ - lib/message_store/postgres/get/category/consumer_group.rb
141
+ - lib/message_store/postgres/get/category/correlation.rb
142
+ - lib/message_store/postgres/get/condition.rb
140
143
  - lib/message_store/postgres/get/stream.rb
141
144
  - lib/message_store/postgres/get/stream/last.rb
142
145
  - lib/message_store/postgres/log.rb