Skip to content

Commit 0a46264

Browse files
Added support for recipient lists in Oracle Avanced Queueing in thin
mode.
1 parent 2012b3d commit 0a46264

File tree

8 files changed

+53
-32
lines changed

8 files changed

+53
-32
lines changed

doc/src/release_notes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ oracledb 3.2.0 (TBD)
1717
Thin Mode Changes
1818
+++++++++++++++++
1919

20+
#) Added support for :ref:`recipient lists <reciplists>` in Oracle Advanced
21+
Queuing.
2022
#) Emulate support for :meth:`Queue.deqmany()` with JSON payloads when using
2123
Oracle Database 21c by internally calling :meth:`Queue.deqone()` as many
2224
times as needed.

doc/src/user_guide/aq.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ types which are detailed below.
5151
**Usage Notes**
5252

5353
For classic queues, the use of :data:`oracledb.ENQ_IMMEDIATE` with bulk
54-
enqueuing, JMS payloads, and :ref:`Recipient Lists <reciplists>` are only
55-
supported in python-oracledb :ref:`Thick mode <enablingthick>`.
54+
enqueuing, and JMS payloads are only supported in python-oracledb
55+
:ref:`Thick mode <enablingthick>`.
5656

5757
Transactional Event Queues do not support :attr:`EnqOptions.transformation`,
5858
:attr:`DeqOptions.transformation`, or :ref:`Recipient Lists <reciplists>`.

src/oracledb/aq.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,6 @@ def _verify_message(self, message: "MessageProperties") -> None:
6868
else:
6969
if not isinstance(message.payload, (str, bytes)):
7070
errors._raise_err(errors.ERR_PAYLOAD_CANNOT_BE_ENQUEUED)
71-
if self.connection.thin:
72-
if message.recipients:
73-
errors._raise_not_supported("specifying AQ message recipients")
7471

7572
@property
7673
def connection(self) -> "connection_module.Connection":

src/oracledb/impl/thin/messages/aq_array.pyx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,11 @@ cdef class AqArrayMessage(AqBaseMessage):
159159
buf.write_uint8(TNS_MSG_TYPE_ROW_DATA)
160160
buf.write_ub4(flags) # aqi flags
161161
self._write_msg_props(buf, props_impl)
162-
buf.write_ub4(0) # num recipients
162+
if props_impl.recipients is None:
163+
buf.write_ub4(0) # num recipients
164+
else:
165+
buf.write_ub4(3 * len(props_impl.recipients))
166+
self._write_recipients(buf, props_impl)
163167
buf.write_sb4(self.enq_options_impl.visibility)
164168
buf.write_ub4(0) # relative msg id
165169
buf.write_sb4(0) # seq deviation

src/oracledb/impl/thin/messages/aq_base.pyx

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,13 @@ cdef class AqBaseMessage(Message):
179179
self._write_value_with_length(buf, props_impl.enq_txn_id)
180180
buf.write_ub4(4) # number of extensions
181181
buf.write_uint8(0x0e) # unknown extra byte
182-
buf.write_extension_values(None, None, TNS_AQ_EXT_KEYWORD_AGENT_NAME)
183-
buf.write_extension_values(None, None,
184-
TNS_AQ_EXT_KEYWORD_AGENT_ADDRESS)
185-
buf.write_extension_values(None, b'\x00',
186-
TNS_AQ_EXT_KEYWORD_AGENT_PROTOCOL)
187-
buf.write_extension_values(None, None,
188-
TNS_AQ_EXT_KEYWORD_ORIGINAL_MSGID)
182+
buf.write_keyword_value_pair(None, None, TNS_AQ_EXT_KEYWORD_AGENT_NAME)
183+
buf.write_keyword_value_pair(None, None,
184+
TNS_AQ_EXT_KEYWORD_AGENT_ADDRESS)
185+
buf.write_keyword_value_pair(None, b'\x00',
186+
TNS_AQ_EXT_KEYWORD_AGENT_PROTOCOL)
187+
buf.write_keyword_value_pair(None, None,
188+
TNS_AQ_EXT_KEYWORD_ORIGINAL_MSGID)
189189
buf.write_ub4(0) # user property
190190
buf.write_ub4(0) # cscn
191191
buf.write_ub4(0) # dscn
@@ -206,6 +206,22 @@ cdef class AqBaseMessage(Message):
206206
else:
207207
buf.write_bytes(props_impl.payload_obj)
208208

209+
210+
cdef int _write_recipients(self, WriteBuffer buf,
211+
ThinMsgPropsImpl props_impl) except -1:
212+
"""
213+
Write the recipient list of the message property object to the
214+
buffer.
215+
"""
216+
cdef:
217+
uint16_t index = 0
218+
str recipient
219+
for recipient in props_impl.recipients:
220+
buf.write_keyword_value_pair(recipient, None, index)
221+
buf.write_keyword_value_pair(None, None, index + 1)
222+
buf.write_keyword_value_pair(None, b'\x00', index + 2)
223+
index += 3
224+
209225
cdef int _write_value_with_length(self, WriteBuffer buf,
210226
object value) except -1:
211227
"""

src/oracledb/impl/thin/messages/aq_enq.pyx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,12 @@ cdef class AqEnqMessage(AqBaseMessage):
6464
buf.write_uint8(1) # queue name (pointer)
6565
buf.write_ub4(len(queue_name_bytes)) # queue name length
6666
self._write_msg_props(buf, self.props_impl)
67-
buf.write_uint8(0) # recipients (pointer)
68-
buf.write_ub4(0) # number of key/value pairs
67+
if self.props_impl.recipients is None:
68+
buf.write_uint8(0) # recipients (pointer)
69+
buf.write_ub4(0) # number of key/value pairs
70+
else:
71+
buf.write_uint8(1) # recipients (pointer)
72+
buf.write_ub4(3 * len(self.props_impl.recipients))
6973
buf.write_ub4(self.enq_options_impl.visibility)
7074
buf.write_uint8(0) # relative message id
7175
buf.write_ub4(0) # relative message length
@@ -115,5 +119,7 @@ cdef class AqEnqMessage(AqBaseMessage):
115119
buf.write_uint8(0) # JSON payload (pointer)
116120

117121
buf.write_bytes_with_length(queue_name_bytes)
122+
if self.props_impl.recipients is not None:
123+
self._write_recipients(buf, self.props_impl)
118124
buf.write_bytes(self.queue_impl.payload_toid)
119125
self._write_payload(buf, self.props_impl)

src/oracledb/impl/thin/packet.pyx

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -895,24 +895,23 @@ cdef class WriteBuffer(Buffer):
895895
self.write_ub4(obj_impl.flags) # flags
896896
self.write_bytes_with_length(packed_data)
897897

898-
cdef int write_extension_values(self, str txt_value, bytes bytes_value,
899-
uint16_t keyword) except -1:
898+
cdef int write_keyword_value_pair(self, str text_value, bytes binary_value,
899+
uint16_t keyword) except -1:
900900
"""
901-
Writes extension's text value, binary value and keyword entry to the
902-
buffer.
901+
Writes a keyword/value pair (text and binary values) to the buffer.
903902
"""
904-
cdef bytes txt_value_bytes
905-
if txt_value is None:
906-
self.write_uint8(0)
903+
cdef bytes text_value_bytes
904+
if text_value is None:
905+
self.write_ub4(0)
907906
else:
908-
txt_value_bytes = txt_value.encode()
909-
self.write_ub4(len(txt_value_bytes))
910-
self.write_bytes_with_length(txt_value_bytes)
911-
if bytes_value is None:
912-
self.write_uint8(0)
907+
text_value_bytes = text_value.encode()
908+
self.write_ub4(len(text_value_bytes))
909+
self.write_bytes_with_length(text_value_bytes)
910+
if binary_value is None:
911+
self.write_ub4(0)
913912
else:
914-
self.write_ub4(len(bytes_value))
915-
self.write_bytes_with_length(bytes_value)
913+
self.write_ub4(len(binary_value))
914+
self.write_bytes_with_length(binary_value)
916915
self.write_ub2(keyword)
917916

918917
cdef int write_lob_with_length(self, BaseThinLobImpl lob_impl) except -1:

tests/test_2700_aq_dbobject.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -410,9 +410,6 @@ def test_2718(self):
410410
props = queue.deqone()
411411
self.assertEqual(props.msgid, actual_msgid)
412412

413-
@unittest.skipIf(
414-
test_env.get_is_thin(), "Thin mode doesn't support recipient list yet"
415-
)
416413
def test_2719(self):
417414
"2719 - verify use of recipients property"
418415
books_type = self.conn.gettype(self.book_type_name)

0 commit comments

Comments
 (0)