pg-replication-protocol 0.0.5 → 0.0.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 07bd494baf2df079a175855749b79dc41460c5903a58e3cef89f7ac1304e6e9b
4
- data.tar.gz: 28ad5dced1a6a73c84a62ce6eae434dbde34883378555c8bac7674d477928627
3
+ metadata.gz: fc030b9fec7b0a01acbf309813046913b36da4ddc289e7201d17e78b6de0d471
4
+ data.tar.gz: 7fa53e2ce183c315b70812f1d58af99afa492419d208704f2cbf97d67a7e57f8
5
5
  SHA512:
6
- metadata.gz: 7bd50c203eb711090bdbb0b16d745e46472d936191ac3c3653138bc9db42cecd6b1ed51a625eeae5194be3ca17c66e6f8a05dd4a860979a791d4fa54eee74139
7
- data.tar.gz: 3ddaf038c9cdfab3c05c4ac2e6eac8c1799c7a0b1d334a4657b19a9251feeac835784bbdec5a94fba43260f50b932441cd49786f1f573c7a607687a742ef8eb4
6
+ metadata.gz: 2a9ab36b64b600bbd3f306d818f2bfc06666e520bba5588614ed5783c78227b1277522f03737de90b185ef659bd099cbb4064ece4d2afbafe5e8815e71916ca8
7
+ data.tar.gz: a94a6ca7fddac35799d4dad64099aacc0af68b4d7e37ffcd777d504852a29f26016595d3e5a15c3a3a9174a9706709787342f80fb059e4a01292d00f219e8df6
data/Gemfile CHANGED
@@ -5,6 +5,8 @@ source "https://rubygems.org"
5
5
  gemspec
6
6
 
7
7
  gem "rake", "~> 13.0"
8
+ gem "base64"
9
+ gem "rbs"
8
10
 
9
11
  group :test do
10
12
  gem "rspec", "~> 3.0"
data/Gemfile.lock CHANGED
@@ -1,20 +1,24 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pg-replication-protocol (0.0.5)
4
+ pg-replication-protocol (0.0.7)
5
5
  pg (~> 1.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
+ base64 (0.3.0)
10
11
  diff-lcs (1.5.1)
11
12
  docker-api (2.4.0)
12
13
  excon (>= 0.64.0)
13
14
  multi_json
14
15
  excon (1.2.1)
16
+ logger (1.7.0)
15
17
  multi_json (1.15.0)
16
18
  pg (1.5.9)
17
19
  rake (13.2.1)
20
+ rbs (3.9.4)
21
+ logger
18
22
  rspec (3.13.0)
19
23
  rspec-core (~> 3.13.0)
20
24
  rspec-expectations (~> 3.13.0)
@@ -38,8 +42,10 @@ PLATFORMS
38
42
  x86_64-linux
39
43
 
40
44
  DEPENDENCIES
45
+ base64
41
46
  pg-replication-protocol!
42
47
  rake (~> 13.0)
48
+ rbs
43
49
  rspec (~> 3.0)
44
50
  testcontainers-postgres
45
51
 
data/Rakefile CHANGED
@@ -2,3 +2,7 @@
2
2
 
3
3
  require "bundler/gem_tasks"
4
4
  task default: %i[]
5
+
6
+ task :test do
7
+ sh "bundle exec rbs test --target PG::Replication::* bundle exec rspec"
8
+ end
@@ -19,19 +19,19 @@ module PG
19
19
  end
20
20
 
21
21
  def read_int8
22
- read(1).unpack("C").first
22
+ readbyte
23
23
  end
24
24
 
25
25
  def read_int16
26
- read(2).unpack("n").first
26
+ read_bytes(2).unpack("n").first
27
27
  end
28
28
 
29
29
  def read_int32
30
- read(4).unpack("N").first
30
+ read_bytes(4).unpack("N").first
31
31
  end
32
32
 
33
33
  def read_int64
34
- read(8).unpack("Q>").first
34
+ read_bytes(8).unpack("Q>").first
35
35
  end
36
36
 
37
37
  def read_timestamp
@@ -50,6 +50,14 @@ module PG
50
50
  end
51
51
  end
52
52
  end
53
+
54
+ private
55
+
56
+ def read_bytes(n)
57
+ bytes = read(n)
58
+ raise EOFError if bytes.nil? || bytes.size < n
59
+ bytes
60
+ end
53
61
  end
54
62
  end
55
63
  end
@@ -13,7 +13,19 @@ module PG
13
13
  Update = Data.define(:oid, :key, :old, :new)
14
14
  Delete = Data.define(:oid, :key, :old)
15
15
  Truncate = Data.define(:oid)
16
- Tuple = Data.define(:type, :data)
16
+ Tuple = Data.define(:type, :data) do
17
+ def text?
18
+ type == "t"
19
+ end
20
+
21
+ def binary?
22
+ type == "b"
23
+ end
24
+
25
+ def toast?
26
+ type == "u"
27
+ end
28
+ end
17
29
  Column = Data.define(:flags, :name, :oid, :modifier) do
18
30
  def key?
19
31
  flags == 1
@@ -150,8 +162,10 @@ module PG
150
162
  end
151
163
 
152
164
  def self.read_tuple(buffer)
153
- case buffer.read_char
154
- in type if type == "n"
165
+ case (type = buffer.read_char)
166
+ in "n"
167
+ Tuple.new(type:, data: nil)
168
+ in "u"
155
169
  Tuple.new(type:, data: nil)
156
170
  in type
157
171
  size = buffer.read_int32
@@ -2,6 +2,6 @@
2
2
 
3
3
  module PG
4
4
  module Replication
5
- VERSION = "0.0.5"
5
+ VERSION = "0.0.7"
6
6
  end
7
7
  end
@@ -48,15 +48,18 @@ module PG
48
48
  case (msg = Protocol.read_message(Buffer.new(StringIO.new(data))))
49
49
  in Protocol::XLogData(lsn:, data:) if auto_keep_alive
50
50
  y << msg
51
- standby_status_update(write_lsn: lsn)
52
- @last_confirmed_lsn = lsn
51
+ standby_status_update(write_lsn: lsn) if lsn > 0
53
52
  last_keep_alive = Time.now
54
53
 
55
- in Protocol::PrimaryKeepalive(server_time:, asap: true) if auto_keep_alive
56
- standby_status_update(write_lsn: @last_confirmed_lsn)
54
+ in Protocol::PrimaryKeepalive(current_lsn:, server_time:, asap: true) if auto_keep_alive
55
+ standby_status_update(write_lsn: current_lsn)
57
56
  last_keep_alive = Time.now
58
57
  y << msg
59
58
 
59
+ in Protocol::PrimaryKeepalive(current_lsn:)
60
+ y << msg
61
+ @last_confirmed_lsn = [@last_confirmed_lsn, current_lsn].compact.max
62
+
60
63
  else
61
64
  y << msg
62
65
  end
@@ -0,0 +1,283 @@
1
+ module PG
2
+ module Replication
3
+ module Protocol
4
+ class PrimaryKeepalive < ::Data
5
+ def self.new: (Integer current_lsn, Time server_time, Boolean asap) -> instance
6
+ | (current_lsn: Integer, server_time: Time, asap: Boolean) -> instance
7
+
8
+ def self.[]: (Integer current_lsn, Time server_time, Boolean asap) -> instance
9
+ | (current_lsn: Integer, server_time: Time, asap: Boolean) -> instance
10
+
11
+ def self.members: () -> [ :current_lsn, :server_time, :asap ]
12
+
13
+ def members: () -> [ :current_lsn, :server_time, :asap ]
14
+
15
+ attr_reader current_lsn: Integer
16
+
17
+ attr_reader server_time: Time
18
+
19
+ attr_reader asap: Boolean
20
+ end
21
+
22
+ class XLogData[T] < ::Data
23
+ def self.new: (Integer lsn, Integer current_lsn, Time server_time, T data) -> instance
24
+ | (lsn: Integer, current_lsn: Integer, server_time: Time, data: T) -> instance
25
+
26
+ def self.[]: (Integer lsn, Integer current_lsn, Time server_time, T data) -> instance
27
+ | (lsn: Integer, current_lsn: Integer, server_time: Time, data: T) -> instance
28
+
29
+ def self.members: () -> [ :lsn, :current_lsn, :server_time, :data ]
30
+
31
+ def members: () -> [ :lsn, :current_lsn, :server_time, :data ]
32
+
33
+ attr_reader lsn: Integer
34
+
35
+ attr_reader current_lsn: Integer
36
+
37
+ attr_reader server_time: Time
38
+
39
+ attr_reader data: T
40
+ end
41
+ end
42
+
43
+ module PGOutput
44
+ class Begin < ::Data
45
+ def self.new: (Integer final_lsn, Time timestamp, Integer xid) -> instance
46
+ | (final_lsn: Integer, timestamp: Time, xid: Integer) -> instance
47
+
48
+ def self.[]: (Integer final_lsn, Time timestamp, Integer xid) -> instance
49
+ | (final_lsn: Integer, timestamp: Time, xid: Integer) -> instance
50
+
51
+ def self.members: () -> [ :final_lsn, :timestamp, :xid ]
52
+
53
+ def members: () -> [ :final_lsn, :timestamp, :xid ]
54
+
55
+ attr_reader final_lsn: Integer
56
+
57
+ attr_reader timestamp: Time
58
+
59
+ attr_reader xid: Integer
60
+ end
61
+
62
+ class Column < ::Data
63
+ def self.new: (Integer flags, String name, Integer oid, Integer modifier) -> instance
64
+ | (flags: Integer, name: String, oid: Integer, modifier: Integer) -> instance
65
+
66
+ def self.[]: (Integer flags, String name, Integer oid, Integer modifier) -> instance
67
+ | (flags: Integer, name: String, oid: Integer, modifier: Integer) -> instance
68
+
69
+ def self.members: () -> [ :flags, :name, :oid, :modifier ]
70
+
71
+ def members: () -> [ :flags, :name, :oid, :modifier ]
72
+
73
+ attr_reader flags: Integer
74
+
75
+ attr_reader name: String
76
+
77
+ attr_reader oid: Integer
78
+
79
+ attr_reader modifier: Integer
80
+
81
+ def key?: () -> Boolean
82
+ end
83
+
84
+ class Commit < ::Data
85
+ def self.new: (Integer lsn, Integer end_lsn, Time timestamp) -> instance
86
+ | (lsn: Integer, end_lsn: Integer, timestamp: Time) -> instance
87
+
88
+ def self.[]: (Integer lsn, Integer end_lsn, Time timestamp) -> instance
89
+ | (lsn: Integer, end_lsn: Integer, timestamp: Time) -> instance
90
+
91
+ def self.members: () -> [ :lsn, :end_lsn, :timestamp ]
92
+
93
+ def members: () -> [ :lsn, :end_lsn, :timestamp ]
94
+
95
+ attr_reader lsn: Integer
96
+
97
+ attr_reader end_lsn: Integer
98
+
99
+ attr_reader timestamp: Time
100
+ end
101
+
102
+ class Delete < ::Data
103
+ def self.new: (Integer oid, Array[String] key, Array[String] old) -> instance
104
+ | (oid: Integer, key: Array[String], old: Array[String]) -> instance
105
+
106
+ def self.[]: (Integer oid, Array[String] key, Array[String] old) -> instance
107
+ | (oid: Integer, key: Array[String], old: Array[String]) -> instance
108
+
109
+ def self.members: () -> [ :oid, :key, :old ]
110
+
111
+ def members: () -> [ :oid, :key, :old ]
112
+
113
+ attr_reader oid: Integer
114
+
115
+ attr_reader key: Array[String]
116
+
117
+ attr_reader old: Array[String]
118
+ end
119
+
120
+ class Insert < ::Data
121
+ def self.new: (Integer oid, Array[String] new) -> instance
122
+ | (oid: Integer, new: Array[String]) -> instance
123
+
124
+ def self.[]: (Integer oid, Array[String] new) -> instance
125
+ | (oid: Integer, new: Array[String]) -> instance
126
+
127
+ def self.members: () -> [ :oid, :new ]
128
+
129
+ def members: () -> [ :oid, :new ]
130
+
131
+ attr_reader oid: Integer
132
+
133
+ attr_reader new: Array[String]
134
+ end
135
+
136
+ class Message < ::Data
137
+ def self.new: (Boolean transactional, Integer lsn, String? prefix, String? content) -> instance
138
+ | (transactional: Boolean, lsn: Integer, prefix: String?, content: String?) -> instance
139
+
140
+ def self.[]: (Boolean transactional, Integer lsn, String? prefix, String? content) -> instance
141
+ | (transactional: Boolean, lsn: Integer, prefix: String?, content: String?) -> instance
142
+
143
+ def self.members: () -> [ :transactional, :lsn, :prefix, :content ]
144
+
145
+ def members: () -> [ :transactional, :lsn, :prefix, :content ]
146
+
147
+ attr_reader transactional: Boolean
148
+
149
+ attr_reader lsn: Integer
150
+
151
+ attr_reader prefix: String?
152
+
153
+ attr_reader content: String?
154
+ end
155
+
156
+ class Origin < ::Data
157
+ def self.new: (Integer commit_lsn, String name) -> instance
158
+ | (commit_lsn: Integer, name: String) -> instance
159
+
160
+ def self.[]: (Integer commit_lsn, String name) -> instance
161
+ | (commit_lsn: Integer, name: String) -> instance
162
+
163
+ def self.members: () -> [ :commit_lsn, :name ]
164
+
165
+ def members: () -> [ :commit_lsn, :name ]
166
+
167
+ attr_reader commit_lsn: Integer
168
+
169
+ attr_reader name: String
170
+ end
171
+
172
+ class Relation < ::Data
173
+ def self.new: (Integer oid, String namespace, String name, String replica_identity, Array[PG::Replication::PGOutput::Column] columns) -> instance
174
+ | (oid: Integer, namespace: String, name: String, replica_identity: String, columns: Array[PG::Replication::PGOutput::Column]) -> instance
175
+
176
+ def self.[]: (Integer oid, String namespace, String name, String replica_identity, Array[PG::Replication::PGOutput::Column] columns) -> instance
177
+ | (oid: Integer, namespace: String, name: String, replica_identity: String, columns: Array[PG::Replication::PGOutput::Column]) -> instance
178
+
179
+ def self.members: () -> [ :oid, :namespace, :name, :replica_identity, :columns ]
180
+
181
+ def members: () -> [ :oid, :namespace, :name, :replica_identity, :columns ]
182
+
183
+ attr_reader oid: Integer
184
+
185
+ attr_reader namespace: String
186
+
187
+ attr_reader name: String
188
+
189
+ attr_reader replica_identity: String
190
+
191
+ attr_reader columns: Array[PG::Replication::PGOutput::Column]
192
+ end
193
+
194
+ class Truncate < ::Data
195
+ def self.new: (Integer oid) -> instance
196
+ | (oid: Integer) -> instance
197
+
198
+ def self.[]: (Integer oid) -> instance
199
+ | (oid: Integer) -> instance
200
+
201
+ def self.members: () -> [ :oid ]
202
+
203
+ def members: () -> [ :oid ]
204
+
205
+ attr_reader oid: Integer
206
+ end
207
+
208
+ class Tuple < ::Data
209
+ def self.new: (String type, String? data) -> instance
210
+ | (type: String, data: String?) -> instance
211
+
212
+ def self.[]: (String type, String? data) -> instance
213
+ | (type: String, data: String?) -> instance
214
+
215
+ def self.members: () -> [ :type, :data ]
216
+
217
+ def members: () -> [ :type, :data ]
218
+
219
+ attr_reader type: String
220
+
221
+ attr_reader data: String?
222
+
223
+ def text?: () -> Boolean
224
+
225
+ def binary?: () -> Boolean
226
+
227
+ def toast?: () -> Boolean
228
+ end
229
+
230
+ class Type < ::Data
231
+ def self.new: (Integer oid, String namespace, String name) -> instance
232
+ | (oid: Integer, namespace: String, name: String) -> instance
233
+
234
+ def self.[]: (Integer oid, String namespace, String name) -> instance
235
+ | (oid: Integer, namespace: String, name: String) -> instance
236
+
237
+ def self.members: () -> [ :oid, :namespace, :name ]
238
+
239
+ def members: () -> [ :oid, :namespace, :name ]
240
+
241
+ attr_reader oid: Integer
242
+
243
+ attr_reader namespace: String
244
+
245
+ attr_reader name: String
246
+ end
247
+
248
+ class Update < ::Data
249
+ def self.new: (Integer oid, Array[String] key, Array[String] old, Array[String] new) -> instance
250
+ | (oid: Integer, key: Array[String], old: Array[String], new: Array[String]) -> instance
251
+
252
+ def self.[]: (Integer oid, Array[String] key, Array[String] old, Array[String] new) -> instance
253
+ | (oid: Integer, key: Array[String], old: Array[String], new: Array[String]) -> instance
254
+
255
+ def self.members: () -> [ :oid, :key, :old, :new ]
256
+
257
+ def members: () -> [ :oid, :key, :old, :new ]
258
+
259
+ attr_reader oid: Integer
260
+
261
+ attr_reader key: Array[String]
262
+
263
+ attr_reader old: Array[String]
264
+
265
+ attr_reader new: Array[String]
266
+ end
267
+ end
268
+
269
+ @last_confirmed_lsn: Integer?
270
+
271
+ def start_replication_slot: (String slot, ?logical: bool, ?auto_keep_alive: bool, ?location: ::String, **untyped params) -> Enumerator::Lazy[PG::Replication::Protocol::PrimaryKeepalive | PG::Replication::Protocol::XLogData[String]]
272
+
273
+ def start_pgoutput_replication_slot: (String slot, Array[String] publication_names, **untyped kwargs) -> Enumerator::Lazy[PG::Replication::Protocol::PrimaryKeepalive | PG::Replication::Protocol::XLogData[PG::Replication::PGOutput]]
274
+
275
+ def standby_status_update: (write_lsn: Integer, ?flush_lsn: Integer, ?apply_lsn: Integer, ?timestamp: Time, ?reply: bool) -> void
276
+
277
+ def last_confirmed_lsn: () -> Integer?
278
+
279
+ def wal_receiver_status_interval: () -> Integer
280
+
281
+ def confirmed_slot_lsn: (String slot) -> Integer?
282
+ end
283
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg-replication-protocol
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Navarro
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-06-04 00:00:00.000000000 Z
10
+ date: 2025-06-22 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: pg
@@ -41,6 +41,7 @@ files:
41
41
  - lib/pg/replication/protocol.rb
42
42
  - lib/pg/replication/version.rb
43
43
  - pg-replication-protocol.gemspec
44
+ - sig/pg/replication.rbs
44
45
  licenses:
45
46
  - MIT
46
47
  metadata: