pgmq-ruby 0.3.0 → 0.5.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.
@@ -10,20 +10,21 @@ module PGMQ
10
10
  # Creates a new queue
11
11
  #
12
12
  # @param queue_name [String] name of the queue to create
13
- # @return [void]
13
+ # @return [Boolean] true if queue was created, false if it already existed
14
14
  # @raise [PGMQ::Errors::InvalidQueueNameError] if queue name is invalid
15
15
  # @raise [PGMQ::Errors::ConnectionError] if database operation fails
16
16
  #
17
17
  # @example
18
- # client.create("orders")
18
+ # client.create("orders") # => true (created)
19
+ # client.create("orders") # => false (already exists)
19
20
  def create(queue_name)
20
21
  validate_queue_name!(queue_name)
21
22
 
22
23
  with_connection do |conn|
23
- conn.exec_params('SELECT pgmq.create($1::text)', [queue_name])
24
+ existed = queue_exists?(conn, queue_name)
25
+ conn.exec_params("SELECT pgmq.create($1::text)", [queue_name])
26
+ !existed
24
27
  end
25
-
26
- nil
27
28
  end
28
29
 
29
30
  # Creates a partitioned queue
@@ -33,45 +34,45 @@ module PGMQ
33
34
  # @param queue_name [String] name of the queue
34
35
  # @param partition_interval [String] partition interval (e.g., "daily", "10000")
35
36
  # @param retention_interval [String] retention interval (e.g., "7 days", "100000")
36
- # @return [void]
37
+ # @return [Boolean] true if queue was created, false if it already existed
37
38
  #
38
39
  # @example
39
40
  # client.create_partitioned("big_queue",
40
41
  # partition_interval: "daily",
41
42
  # retention_interval: "7 days"
42
- # )
43
+ # ) # => true
43
44
  def create_partitioned(
44
45
  queue_name,
45
- partition_interval: '10000',
46
- retention_interval: '100000'
46
+ partition_interval: "10000",
47
+ retention_interval: "100000"
47
48
  )
48
49
  validate_queue_name!(queue_name)
49
50
 
50
51
  with_connection do |conn|
52
+ existed = queue_exists?(conn, queue_name)
51
53
  conn.exec_params(
52
- 'SELECT pgmq.create_partitioned($1::text, $2::text, $3::text)',
54
+ "SELECT pgmq.create_partitioned($1::text, $2::text, $3::text)",
53
55
  [queue_name, partition_interval, retention_interval]
54
56
  )
57
+ !existed
55
58
  end
56
-
57
- nil
58
59
  end
59
60
 
60
61
  # Creates an unlogged queue for higher throughput (no crash recovery)
61
62
  #
62
63
  # @param queue_name [String] name of the queue
63
- # @return [void]
64
+ # @return [Boolean] true if queue was created, false if it already existed
64
65
  #
65
66
  # @example
66
- # client.create_unlogged("fast_queue")
67
+ # client.create_unlogged("fast_queue") # => true
67
68
  def create_unlogged(queue_name)
68
69
  validate_queue_name!(queue_name)
69
70
 
70
71
  with_connection do |conn|
71
- conn.exec_params('SELECT pgmq.create_unlogged($1::text)', [queue_name])
72
+ existed = queue_exists?(conn, queue_name)
73
+ conn.exec_params("SELECT pgmq.create_unlogged($1::text)", [queue_name])
74
+ !existed
72
75
  end
73
-
74
- nil
75
76
  end
76
77
 
77
78
  # Drops a queue and its archive table
@@ -85,12 +86,12 @@ module PGMQ
85
86
  validate_queue_name!(queue_name)
86
87
 
87
88
  result = with_connection do |conn|
88
- conn.exec_params('SELECT pgmq.drop_queue($1::text)', [queue_name])
89
+ conn.exec_params("SELECT pgmq.drop_queue($1::text)", [queue_name])
89
90
  end
90
91
 
91
92
  return false if result.ntuples.zero?
92
93
 
93
- result[0]['drop_queue'] == 't'
94
+ result[0]["drop_queue"] == "t"
94
95
  end
95
96
 
96
97
  # Lists all queues
@@ -102,11 +103,26 @@ module PGMQ
102
103
  # queues.each { |q| puts q.queue_name }
103
104
  def list_queues
104
105
  result = with_connection do |conn|
105
- conn.exec('SELECT * FROM pgmq.list_queues()')
106
+ conn.exec("SELECT * FROM pgmq.list_queues()")
106
107
  end
107
108
 
108
109
  result.map { |row| QueueMetadata.new(row) }
109
110
  end
111
+
112
+ private
113
+
114
+ # Checks if a queue exists in the pgmq.meta table
115
+ #
116
+ # @param conn [PG::Connection] database connection
117
+ # @param queue_name [String] name of the queue to check
118
+ # @return [Boolean] true if queue exists, false otherwise
119
+ def queue_exists?(conn, queue_name)
120
+ result = conn.exec_params(
121
+ "SELECT 1 FROM pgmq.meta WHERE queue_name = $1 LIMIT 1",
122
+ [queue_name]
123
+ )
124
+ result.ntuples.positive?
125
+ end
110
126
  end
111
127
  end
112
128
  end
@@ -0,0 +1,268 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PGMQ
4
+ class Client
5
+ # Topic routing operations (AMQP-like patterns)
6
+ #
7
+ # This module provides AMQP-style topic routing for PGMQ, allowing messages
8
+ # to be routed to multiple queues based on pattern matching.
9
+ #
10
+ # Topic patterns support wildcards:
11
+ # - `*` matches exactly one word between dots (e.g., `orders.*` matches `orders.new`)
12
+ # - `#` matches zero or more words (e.g., `orders.#` matches `orders.new.urgent`)
13
+ #
14
+ # @note Requires PGMQ v1.11.0+
15
+ module Topics
16
+ # Binds a topic pattern to a queue
17
+ #
18
+ # Messages sent with routing keys matching this pattern will be delivered
19
+ # to the specified queue.
20
+ #
21
+ # @param pattern [String] topic pattern with optional wildcards (* or #)
22
+ # @param queue_name [String] name of the queue to bind
23
+ # @return [void]
24
+ #
25
+ # @example Bind exact routing key
26
+ # client.bind_topic("orders.new", "new_orders")
27
+ #
28
+ # @example Bind with single-word wildcard
29
+ # client.bind_topic("orders.*", "all_order_events")
30
+ #
31
+ # @example Bind with multi-word wildcard
32
+ # client.bind_topic("orders.#", "order_audit_log")
33
+ def bind_topic(pattern, queue_name)
34
+ validate_queue_name!(queue_name)
35
+
36
+ with_connection do |conn|
37
+ conn.exec_params(
38
+ "SELECT pgmq.bind_topic($1::text, $2::text)",
39
+ [pattern, queue_name]
40
+ )
41
+ end
42
+
43
+ nil
44
+ end
45
+
46
+ # Unbinds a topic pattern from a queue
47
+ #
48
+ # @param pattern [String] topic pattern to unbind
49
+ # @param queue_name [String] name of the queue to unbind from
50
+ # @return [Boolean] true if the binding was removed, false if it didn't exist
51
+ #
52
+ # @example
53
+ # client.unbind_topic("orders.new", "new_orders")
54
+ def unbind_topic(pattern, queue_name)
55
+ validate_queue_name!(queue_name)
56
+
57
+ result = with_connection do |conn|
58
+ conn.exec_params(
59
+ "SELECT pgmq.unbind_topic($1::text, $2::text)",
60
+ [pattern, queue_name]
61
+ )
62
+ end
63
+
64
+ result[0]["unbind_topic"] == "t"
65
+ end
66
+
67
+ # Sends a message via topic routing
68
+ #
69
+ # The message will be delivered to all queues whose bound patterns match
70
+ # the routing key.
71
+ #
72
+ # @param routing_key [String] dot-separated routing key (e.g., "orders.new.priority")
73
+ # @param message [String] message as JSON string
74
+ # @param headers [String, nil] optional headers as JSON string
75
+ # @param delay [Integer] delay in seconds before message becomes visible
76
+ # @return [Integer] count of queues the message was delivered to
77
+ #
78
+ # @example Basic topic send
79
+ # count = client.produce_topic("orders.new", '{"order_id":123}')
80
+ #
81
+ # @example With headers and delay
82
+ # count = client.produce_topic("orders.new.priority",
83
+ # '{"order_id":123}',
84
+ # headers: '{"trace_id":"abc"}',
85
+ # delay: 30)
86
+ def produce_topic(routing_key, message, headers: nil, delay: 0)
87
+ result = with_connection do |conn|
88
+ if headers
89
+ conn.exec_params(
90
+ "SELECT pgmq.send_topic($1::text, $2::jsonb, $3::jsonb, $4::integer)",
91
+ [routing_key, message, headers, delay]
92
+ )
93
+ elsif delay > 0
94
+ conn.exec_params(
95
+ "SELECT pgmq.send_topic($1::text, $2::jsonb, $3::integer)",
96
+ [routing_key, message, delay]
97
+ )
98
+ else
99
+ conn.exec_params(
100
+ "SELECT pgmq.send_topic($1::text, $2::jsonb)",
101
+ [routing_key, message]
102
+ )
103
+ end
104
+ end
105
+
106
+ result[0]["send_topic"].to_i
107
+ end
108
+
109
+ # Sends multiple messages via topic routing
110
+ #
111
+ # All messages will be delivered to all queues whose bound patterns match
112
+ # the routing key.
113
+ #
114
+ # @param routing_key [String] dot-separated routing key
115
+ # @param messages [Array<String>] array of message payloads as JSON strings
116
+ # @param headers [Array<String>, nil] optional array of headers as JSON strings
117
+ # @param delay [Integer] delay in seconds before messages become visible
118
+ # @return [Array<Hash>] array of hashes with :queue_name and :msg_id
119
+ #
120
+ # @example Batch topic send
121
+ # results = client.produce_batch_topic("orders.new", [
122
+ # '{"order_id":1}',
123
+ # '{"order_id":2}'
124
+ # ])
125
+ # # => [{ queue_name: "new_orders", msg_id: "1" }, ...]
126
+ def produce_batch_topic(routing_key, messages, headers: nil, delay: 0)
127
+ return [] if messages.empty?
128
+
129
+ if headers && headers.length != messages.length
130
+ raise ArgumentError,
131
+ "headers array length (#{headers.length}) must match messages array length (#{messages.length})"
132
+ end
133
+
134
+ result = with_connection do |conn|
135
+ encoder = PG::TextEncoder::Array.new
136
+ encoded_messages = encoder.encode(messages)
137
+
138
+ if headers
139
+ encoded_headers = encoder.encode(headers)
140
+ conn.exec_params(
141
+ "SELECT * FROM pgmq.send_batch_topic($1::text, $2::jsonb[], $3::jsonb[], $4::integer)",
142
+ [routing_key, encoded_messages, encoded_headers, delay]
143
+ )
144
+ elsif delay > 0
145
+ conn.exec_params(
146
+ "SELECT * FROM pgmq.send_batch_topic($1::text, $2::jsonb[], $3::integer)",
147
+ [routing_key, encoded_messages, delay]
148
+ )
149
+ else
150
+ conn.exec_params(
151
+ "SELECT * FROM pgmq.send_batch_topic($1::text, $2::jsonb[])",
152
+ [routing_key, encoded_messages]
153
+ )
154
+ end
155
+ end
156
+
157
+ result.map do |row|
158
+ { queue_name: row["queue_name"], msg_id: row["msg_id"] }
159
+ end
160
+ end
161
+
162
+ # Lists all topic bindings
163
+ #
164
+ # @param queue_name [String, nil] optional queue name to filter by
165
+ # @return [Array<Hash>] array of binding hashes with pattern, queue_name, bound_at
166
+ #
167
+ # @example List all bindings
168
+ # bindings = client.list_topic_bindings
169
+ # # => [{ pattern: "orders.*", queue_name: "orders", bound_at: "..." }, ...]
170
+ #
171
+ # @example List bindings for specific queue
172
+ # bindings = client.list_topic_bindings(queue_name: "orders")
173
+ def list_topic_bindings(queue_name: nil)
174
+ result = with_connection do |conn|
175
+ if queue_name
176
+ validate_queue_name!(queue_name)
177
+ conn.exec_params(
178
+ "SELECT pattern, queue_name, bound_at FROM pgmq.list_topic_bindings($1::text)",
179
+ [queue_name]
180
+ )
181
+ else
182
+ conn.exec("SELECT pattern, queue_name, bound_at FROM pgmq.list_topic_bindings()")
183
+ end
184
+ end
185
+
186
+ result.map do |row|
187
+ {
188
+ pattern: row["pattern"],
189
+ queue_name: row["queue_name"],
190
+ bound_at: row["bound_at"]
191
+ }
192
+ end
193
+ end
194
+
195
+ # Tests which queues a routing key would match
196
+ #
197
+ # Useful for debugging topic routing configurations.
198
+ #
199
+ # @param routing_key [String] routing key to test
200
+ # @return [Array<Hash>] array of matched bindings with pattern and queue_name
201
+ #
202
+ # @example Test routing
203
+ # matches = client.test_routing("orders.new.priority")
204
+ # # => [{ pattern: "orders.*", queue_name: "new_orders" }, ...]
205
+ def test_routing(routing_key)
206
+ result = with_connection do |conn|
207
+ conn.exec_params(
208
+ "SELECT pattern, queue_name FROM pgmq.test_routing($1::text)",
209
+ [routing_key]
210
+ )
211
+ end
212
+
213
+ result.map do |row|
214
+ { pattern: row["pattern"], queue_name: row["queue_name"] }
215
+ end
216
+ end
217
+
218
+ # Validates a routing key
219
+ #
220
+ # Routing keys are dot-separated words (no wildcards allowed).
221
+ # Returns false for invalid routing keys (PGMQ raises an error for invalid keys).
222
+ #
223
+ # @param routing_key [String] routing key to validate
224
+ # @return [Boolean] true if valid, false if invalid
225
+ #
226
+ # @example
227
+ # client.validate_routing_key("orders.new.priority") # => true
228
+ # client.validate_routing_key("orders.*") # => false (wildcards not allowed)
229
+ def validate_routing_key(routing_key)
230
+ result = with_connection do |conn|
231
+ conn.exec_params(
232
+ "SELECT pgmq.validate_routing_key($1::text)",
233
+ [routing_key]
234
+ )
235
+ end
236
+
237
+ result[0]["validate_routing_key"] == "t"
238
+ rescue PGMQ::Errors::ConnectionError => e
239
+ # PGMQ raises an error for invalid routing keys
240
+ return false if e.message.include?("invalid characters")
241
+
242
+ raise
243
+ end
244
+
245
+ # Validates a topic pattern
246
+ #
247
+ # Topic patterns can include wildcards: * (single word) or # (zero or more words).
248
+ #
249
+ # @param pattern [String] topic pattern to validate
250
+ # @return [Boolean] true if valid
251
+ #
252
+ # @example
253
+ # client.validate_topic_pattern("orders.*") # => true
254
+ # client.validate_topic_pattern("orders.#") # => true
255
+ # client.validate_topic_pattern("orders.new") # => true
256
+ def validate_topic_pattern(pattern)
257
+ result = with_connection do |conn|
258
+ conn.exec_params(
259
+ "SELECT pgmq.validate_topic_pattern($1::text)",
260
+ [pattern]
261
+ )
262
+ end
263
+
264
+ result[0]["validate_topic_pattern"] == "t"
265
+ end
266
+ end
267
+ end
268
+ end
data/lib/pgmq/client.rb CHANGED
@@ -14,7 +14,7 @@ module PGMQ
14
14
  # password: 'postgres'
15
15
  # )
16
16
  # client.create('my_queue')
17
- # msg_id = client.send('my_queue', { data: 'value' })
17
+ # msg_id = client.produce('my_queue', '{"data":"value"}')
18
18
  # msg = client.read('my_queue', vt: 30)
19
19
  # client.delete('my_queue', msg.msg_id)
20
20
  #
@@ -27,12 +27,13 @@ module PGMQ
27
27
  # Include functional modules (order matters for discoverability)
28
28
  include Transaction # Transaction support (already existed)
29
29
  include QueueManagement # Queue lifecycle (create, drop, list)
30
- include Producer # Message sending operations
30
+ include Producer # Message producing operations
31
31
  include Consumer # Single-queue reading operations
32
32
  include MultiQueue # Multi-queue operations
33
33
  include MessageLifecycle # Message state transitions (pop, delete, archive)
34
- include Maintenance # Queue maintenance (purge, detach_archive)
34
+ include Maintenance # Queue maintenance (purge, notifications)
35
35
  include Metrics # Monitoring and metrics
36
+ include Topics # Topic routing (AMQP-like patterns, PGMQ v1.11.0+)
36
37
 
37
38
  # Default visibility timeout in seconds
38
39
  DEFAULT_VT = 30
@@ -65,15 +66,15 @@ module PGMQ
65
66
  auto_reconnect: true
66
67
  )
67
68
  @connection = if conn_params.is_a?(Connection)
68
- conn_params
69
- else
70
- Connection.new(
71
- conn_params,
72
- pool_size: pool_size,
73
- pool_timeout: pool_timeout,
74
- auto_reconnect: auto_reconnect
75
- )
76
- end
69
+ conn_params
70
+ else
71
+ Connection.new(
72
+ conn_params,
73
+ pool_size: pool_size,
74
+ pool_timeout: pool_timeout,
75
+ auto_reconnect: auto_reconnect
76
+ )
77
+ end
77
78
  end
78
79
 
79
80
  # Closes all connections in the pool
@@ -109,7 +110,7 @@ module PGMQ
109
110
  if queue_name.nil? || queue_name.to_s.strip.empty?
110
111
  raise(
111
112
  Errors::InvalidQueueNameError,
112
- 'Queue name cannot be empty'
113
+ "Queue name cannot be empty"
113
114
  )
114
115
  end
115
116
 
@@ -131,7 +132,7 @@ module PGMQ
131
132
  raise(
132
133
  Errors::InvalidQueueNameError,
133
134
  "Invalid queue name '#{queue_name}': must start with a letter or underscore " \
134
- 'and contain only letters, digits, and underscores'
135
+ "and contain only letters, digits, and underscores"
135
136
  )
136
137
  end
137
138
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pg'
4
- require 'connection_pool'
3
+ require "pg"
4
+ require "connection_pool"
5
5
 
6
6
  module PGMQ
7
7
  # Manages database connections for PGMQ
@@ -45,7 +45,7 @@ module PGMQ
45
45
  if conn_params.nil?
46
46
  raise(
47
47
  PGMQ::Errors::ConfigurationError,
48
- 'Connection parameters are required'
48
+ "Connection parameters are required"
49
49
  )
50
50
  end
51
51
 
@@ -113,12 +113,12 @@ module PGMQ
113
113
  def connection_lost_error?(error)
114
114
  # Common connection lost errors
115
115
  lost_connection_messages = [
116
- 'server closed the connection',
117
- 'connection not open',
118
- 'no connection to the server',
119
- 'terminating connection',
120
- 'connection to server was lost',
121
- 'could not receive data from server'
116
+ "server closed the connection",
117
+ "connection not open",
118
+ "no connection to the server",
119
+ "terminating connection",
120
+ "connection to server was lost",
121
+ "could not receive data from server"
122
122
  ]
123
123
 
124
124
  message = error.message.downcase
@@ -145,7 +145,7 @@ module PGMQ
145
145
  return parse_connection_string(params) if params.is_a?(String)
146
146
  return params if params.is_a?(Hash) && !params.empty?
147
147
 
148
- raise PGMQ::Errors::ConfigurationError, 'Invalid connection parameters format'
148
+ raise PGMQ::Errors::ConfigurationError, "Invalid connection parameters format"
149
149
  end
150
150
 
151
151
  # Parses a PostgreSQL connection string
@@ -173,7 +173,7 @@ module PGMQ
173
173
  ConnectionPool.new(size: @pool_size, timeout: @pool_timeout) do
174
174
  create_connection(params)
175
175
  end
176
- rescue StandardError => e
176
+ rescue => e
177
177
  raise PGMQ::Errors::ConnectionError, "Failed to create connection pool: #{e.message}"
178
178
  end
179
179
 
data/lib/pgmq/message.rb CHANGED
@@ -11,12 +11,13 @@ module PGMQ
11
11
  # puts msg.msg_id # => "123" (String from PG)
12
12
  # puts msg.read_ct # => "1" (String from PG)
13
13
  # puts msg.enqueued_at # => "2025-01-15 10:30:00+00" (String from PG)
14
+ # puts msg.last_read_at # => "2025-01-15 10:31:00+00" (String from PG, nil if never read)
14
15
  # puts msg.vt # => "2025-01-15 10:30:30+00" (String from PG)
15
16
  # puts msg.message # => "{\"order_id\":456}" (Raw JSONB string)
16
17
  # puts msg.headers # => "{\"trace_id\":\"abc123\"}" (Raw JSONB string, optional)
17
18
  # puts msg.queue_name # => "my_queue" (only present for multi-queue operations)
18
19
  class Message < Data.define(
19
- :msg_id, :read_ct, :enqueued_at, :vt, :message, :headers, :queue_name
20
+ :msg_id, :read_ct, :enqueued_at, :last_read_at, :vt, :message, :headers, :queue_name
20
21
  )
21
22
  class << self
22
23
  # Creates a new Message from a database row
@@ -27,19 +28,20 @@ module PGMQ
27
28
  # No parsing, no deserialization, no transformation
28
29
  # The pg gem returns JSONB as String by default
29
30
  super(
30
- msg_id: row['msg_id'],
31
- read_ct: row['read_ct'],
32
- enqueued_at: row['enqueued_at'],
33
- vt: row['vt'],
34
- message: row['message'],
35
- headers: row['headers'], # JSONB column for metadata (optional)
36
- queue_name: row['queue_name'] # nil for single-queue operations
31
+ msg_id: row["msg_id"],
32
+ read_ct: row["read_ct"],
33
+ enqueued_at: row["enqueued_at"],
34
+ last_read_at: row["last_read_at"], # nil if message has never been read
35
+ vt: row["vt"],
36
+ message: row["message"],
37
+ headers: row["headers"], # JSONB column for metadata (optional)
38
+ queue_name: row["queue_name"] # nil for single-queue operations
37
39
  )
38
40
  end
39
41
  end
40
42
 
41
43
  # Alias for msg_id (common in messaging systems)
42
44
  # @return [String]
43
- alias id msg_id
45
+ alias_method :id, :msg_id
44
46
  end
45
47
  end
data/lib/pgmq/metrics.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'time'
3
+ require "time"
4
4
 
5
5
  module PGMQ
6
6
  # Represents metrics for a PGMQ queue
@@ -24,12 +24,12 @@ module PGMQ
24
24
  def new(row, **)
25
25
  # Return raw values as-is from PostgreSQL
26
26
  super(
27
- queue_name: row['queue_name'],
28
- queue_length: row['queue_length'],
29
- newest_msg_age_sec: row['newest_msg_age_sec'],
30
- oldest_msg_age_sec: row['oldest_msg_age_sec'],
31
- total_messages: row['total_messages'],
32
- scrape_time: row['scrape_time']
27
+ queue_name: row["queue_name"],
28
+ queue_length: row["queue_length"],
29
+ newest_msg_age_sec: row["newest_msg_age_sec"],
30
+ oldest_msg_age_sec: row["oldest_msg_age_sec"],
31
+ total_messages: row["total_messages"],
32
+ scrape_time: row["scrape_time"]
33
33
  )
34
34
  end
35
35
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'time'
3
+ require "time"
4
4
 
5
5
  module PGMQ
6
6
  # Represents metadata about a PGMQ queue
@@ -18,20 +18,20 @@ module PGMQ
18
18
  def new(row, **)
19
19
  # Return raw values as-is from PostgreSQL
20
20
  super(
21
- queue_name: row['queue_name'],
22
- created_at: row['created_at'],
23
- is_partitioned: row['is_partitioned'],
24
- is_unlogged: row['is_unlogged']
21
+ queue_name: row["queue_name"],
22
+ created_at: row["created_at"],
23
+ is_partitioned: row["is_partitioned"],
24
+ is_unlogged: row["is_unlogged"]
25
25
  )
26
26
  end
27
27
  end
28
28
 
29
29
  # Alias for is_partitioned
30
30
  # @return [String] 't' or 'f' from PostgreSQL
31
- alias partitioned? is_partitioned
31
+ alias_method :partitioned?, :is_partitioned
32
32
 
33
33
  # Alias for is_unlogged
34
34
  # @return [String] 't' or 'f' from PostgreSQL
35
- alias unlogged? is_unlogged
35
+ alias_method :unlogged?, :is_unlogged
36
36
  end
37
37
  end
@@ -12,13 +12,13 @@ module PGMQ
12
12
  #
13
13
  # @example Atomic multi-queue operations
14
14
  # client.transaction do |txn|
15
- # txn.send("orders", { order_id: 123 })
16
- # txn.send("notifications", { type: "order_created" })
15
+ # txn.produce("orders", '{"order_id":123}')
16
+ # txn.produce("notifications", '{"type":"order_created"}')
17
17
  # end
18
18
  #
19
19
  # @example Automatic rollback on error
20
20
  # client.transaction do |txn|
21
- # txn.send("orders", { order_id: 123 })
21
+ # txn.produce("orders", '{"order_id":123}')
22
22
  # raise "Error" # Both operations rolled back
23
23
  # end
24
24
  module Transaction
@@ -33,7 +33,7 @@ module PGMQ
33
33
  #
34
34
  # @example
35
35
  # client.transaction do |txn|
36
- # msg_id = txn.send("queue", { data: "test" })
36
+ # msg_id = txn.produce("queue", '{"data":"test"}')
37
37
  # txn.delete("queue", msg_id)
38
38
  # end
39
39
  def transaction
@@ -67,19 +67,6 @@ module PGMQ
67
67
  @parent.respond_to?(method, true) ? @parent.__send__(method, ...) : super
68
68
  end
69
69
 
70
- # Override Object#send to call parent's send method
71
- # @param queue_name [String] queue name
72
- # @param message [String] message as JSON string
73
- # @param delay [Integer] delay in seconds
74
- # @return [String] message ID
75
- def send(
76
- queue_name,
77
- message,
78
- delay: 0
79
- )
80
- @parent.send(queue_name, message, delay: delay)
81
- end
82
-
83
70
  # Check if method exists on parent
84
71
  # @param method [Symbol] method name
85
72
  # @param include_private [Boolean] include private methods
data/lib/pgmq/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module PGMQ
4
4
  # Current version of the pgmq-ruby gem
5
- VERSION = '0.3.0'
5
+ VERSION = "0.5.0"
6
6
  end