Skip to content

Commit 31c0bec

Browse files
Added support for enqueuing and dequeuing JSON payloads using Advanced
Queuing (AQ).
1 parent 2860bda commit 31c0bec

File tree

9 files changed

+266
-26
lines changed

9 files changed

+266
-26
lines changed

doc/src/functions/dpiConn.rst

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,50 @@ handles.
607607
is created by this function.
608608

609609

610+
.. function:: int dpiConn_newJson(dpiConn* conn, dpiJson** json)
611+
612+
Returns a reference to a new JSON object. This object can be used as the
613+
payload in a message enqueued in a JSON queue, or as the value for a
614+
variable. The reference should be released by calling
615+
:func:`dpiJson_release()` as soon as it is no longer needed.
616+
617+
The function returns DPI_SUCCESS for success and DPI_FAILURE for failure.
618+
619+
**conn** [IN] -- a reference to the connection in which the JSON object is
620+
going to be used. If the reference is NULL or invalid, an error is
621+
returned.
622+
623+
**json** [OUT] -- a pointer to a reference to the JSON object that
624+
is created by this function.
625+
626+
627+
.. function:: int dpiConn_newJsonQueue(dpiConn* conn, const char* name, \
628+
uint32_t nameLength, dpiQueue** queue)
629+
630+
Returns a reference to a new queue which enqueues and dequeues messages
631+
from Advanced Queueing (AQ) with a JSON payload. The reference should be
632+
released by calling :func:`dpiQueue_release()` as soon as it is no longer
633+
needed. For queues with RAW or Database Object payloads, use the method
634+
:func:`dpiConn_newQueue()` instead.
635+
636+
The function returns DPI_SUCCESS for success and DPI_FAILURE for failure.
637+
638+
**conn** [IN] -- a reference to the connection in which messages are to be
639+
dequeued or enqueued. If the reference is NULL or invalid, an error is
640+
returned.
641+
642+
**name** [IN] -- the name of the queue, as a byte string in the encoding
643+
used for CHAR data. Note that UTF-16 encodings are not currently supported
644+
by AQ.
645+
646+
**nameLength** [IN] -- the length of the name parameter, in bytes.
647+
648+
**queue** [OUT] -- a reference to the newly created queue which will be
649+
populated upon successful completion of this function. The reference should
650+
be released by calling :func:`dpiQueue_release()` as soon as it is no
651+
longer needed.
652+
653+
610654
.. function:: int dpiConn_newMsgProps(dpiConn* conn, dpiMsgProps** props)
611655

612656
Returns a reference to a new set of message properties, used in enqueuing

doc/src/functions/dpiMsgProps.rst

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ releasing the last reference by calling the function
195195

196196
Returns the payload associated with the message properties. The payload can
197197
either be an object or an arbitrary series of bytes and is available after
198-
the a call to :func:`dpiQueue_deqOne()` or :func:`dpiQueue_deqMany()`.
198+
a call to :func:`dpiQueue_deqOne()` or :func:`dpiQueue_deqMany()`.
199199

200200
The function returns DPI_SUCCESS for success and DPI_FAILURE for failure.
201201

@@ -218,6 +218,25 @@ releasing the last reference by calling the function
218218
also be NULL.
219219

220220

221+
.. function:: int dpiMsgProps_getPayloadJson(dpiMsgProps* props, \
222+
dpiJson** json)
223+
224+
Returns the payload associated with the message properties, The payload
225+
must be a JSON object and is available after the call to
226+
:func:`dpiQueue_deqOne()` or :func:`dpiQueue_deqMany()`; otherwise, the
227+
value NULL will be returned.
228+
229+
The function returns DPI_SUCCESS for success and DPI_FAILURE for failure.
230+
231+
**props** [IN] -- a reference to the message properties from which the
232+
payload is to be retrieved. If the reference is NULL or invalid, an error
233+
is returned.
234+
235+
**json** [OUT] -- a reference to a JSON object which will be populated upon
236+
successful completion of this function. If the payload is not a JSON
237+
object, this value will be NULL.
238+
239+
221240
.. function:: int dpiMsgProps_getPriority(dpiMsgProps* props, int32_t* value)
222241

223242
Returns the priority assigned to the message. See function
@@ -376,6 +395,22 @@ releasing the last reference by calling the function
376395
**valueLength** [IN] -- the length of the value parameter in bytes.
377396

378397

398+
.. function:: int dpiMsgProps_setPayloadJson(dpiMsgProps* props, dpiJson* json)
399+
400+
Sets the payload for the message as a JSON object. This value will be used
401+
when the message is enqueued using :func:`dpiQueue_enqOne()` or
402+
:func:`dpiQueue_enqMany()`.
403+
404+
The function returns DPI_SUCCESS for success and DPI_FAILURE for failure.
405+
406+
**props** [IN] -- a reference to the message properties on which the
407+
payload is to be set. If the reference is NULL or invalid, an error is
408+
returned.
409+
410+
**json** [IN] -- a reference to the JSON object that will be used as the
411+
message payload. If the reference is NULL or invalid, an error is returned.
412+
413+
379414
.. function:: int dpiMsgProps_setPayloadObject(dpiMsgProps* props, \
380415
dpiObject* obj)
381416

doc/src/releasenotes.rst

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@ ODPI-C Release notes
44
Version 4.5 (TBD)
55
-----------------
66

7-
#) Added support for OAuth token authentication when creating standalone
8-
connections and connection pools.
7+
#) Added support for OAuth token authentication when creating standalone
8+
connections and connection pools.
9+
#) Added support for enqueuing and dequeuing JSON payloads using Advanced
10+
Queuing (AQ). Functions :func:`dpiConn_newJson()`,
11+
:func:`dpiConn_newJsonQueue()`, :func:`dpiMsgProps_getPayloadJson()` and
12+
:func:`dpiMsgProps_setPayloadJson()` were added to support this
13+
functionality.
914

1015

1116
Version 4.4.1 (June 14, 2022)

doc/src/user_guide/round_trips.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,12 @@ back.
109109
* - :func:`dpiConn_newEnqOptions()`
110110
- No
111111
-
112+
* - :func:`dpiConn_newJson()`
113+
- No
114+
-
115+
* - :func:`dpiConn_newJsonQueue()`
116+
- No
117+
-
112118
* - :func:`dpiConn_newMsgProps()`
113119
- No
114120
-
@@ -522,6 +528,9 @@ back.
522528
* - :func:`dpiMsgProps_getPayload()`
523529
- No
524530
-
531+
* - :func:`dpiMsgProps_getPayloadJson()`
532+
- No
533+
-
525534
* - :func:`dpiMsgProps_getPriority()`
526535
- No
527536
-
@@ -552,6 +561,9 @@ back.
552561
* - :func:`dpiMsgProps_setPayloadBytes()`
553562
- No
554563
-
564+
* - :func:`dpiMsgProps_setPayloadJson()`
565+
- No
566+
-
555567
* - :func:`dpiMsgProps_setPayloadObject()`
556568
- No
557569
-

include/dpi.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,13 @@ DPI_EXPORT int dpiConn_newDeqOptions(dpiConn *conn, dpiDeqOptions **options);
10051005
// create a new enqueue options object and return it
10061006
DPI_EXPORT int dpiConn_newEnqOptions(dpiConn *conn, dpiEnqOptions **options);
10071007

1008+
// create a new, empty JSON
1009+
DPI_EXPORT int dpiConn_newJson(dpiConn *conn, dpiJson **json);
1010+
1011+
// create a new AQ queue with JSON payload
1012+
DPI_EXPORT int dpiConn_newJsonQueue(dpiConn *conn, const char *name,
1013+
uint32_t nameLength, dpiQueue **queue);
1014+
10081015
// create a new message properties object and return it
10091016
DPI_EXPORT int dpiConn_newMsgProps(dpiConn *conn, dpiMsgProps **props);
10101017

@@ -1470,6 +1477,9 @@ DPI_EXPORT int dpiMsgProps_getOriginalMsgId(dpiMsgProps *props,
14701477
DPI_EXPORT int dpiMsgProps_getPayload(dpiMsgProps *props, dpiObject **obj,
14711478
const char **value, uint32_t *valueLength);
14721479

1480+
// return the payload of the message (JSON)
1481+
DPI_EXPORT int dpiMsgProps_getPayloadJson(dpiMsgProps *props, dpiJson **json);
1482+
14731483
// return the priority of the message
14741484
DPI_EXPORT int dpiMsgProps_getPriority(dpiMsgProps *props, int32_t *value);
14751485

@@ -1502,6 +1512,9 @@ DPI_EXPORT int dpiMsgProps_setOriginalMsgId(dpiMsgProps *props,
15021512
DPI_EXPORT int dpiMsgProps_setPayloadBytes(dpiMsgProps *props,
15031513
const char *value, uint32_t valueLength);
15041514

1515+
// set the payload of the message (as JSON)
1516+
DPI_EXPORT int dpiMsgProps_setPayloadJson(dpiMsgProps *props, dpiJson *json);
1517+
15051518
// set the payload of the message (as an object)
15061519
DPI_EXPORT int dpiMsgProps_setPayloadObject(dpiMsgProps *props,
15071520
dpiObject *obj);

src/dpiConn.c

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -722,10 +722,24 @@ static int dpiConn__getHandles(dpiConn *conn, dpiError *error)
722722
}
723723

724724

725+
//-----------------------------------------------------------------------------
726+
// dpiConn__getJsonTDO() [INTERNAL]
727+
// Internal method used for ensuring that the JSON TDO has been cached on the
728+
// connection.
729+
//-----------------------------------------------------------------------------
730+
int dpiConn__getJsonTDO(dpiConn *conn, dpiError *error)
731+
{
732+
if (conn->jsonTDO)
733+
return DPI_SUCCESS;
734+
return dpiOci__typeByName(conn, "SYS", 3, "JSON", 4, &conn->jsonTDO,
735+
error);
736+
}
737+
738+
725739
//-----------------------------------------------------------------------------
726740
// dpiConn__getRawTDO() [INTERNAL]
727741
// Internal method used for ensuring that the RAW TDO has been cached on the
728-
//connection.
742+
// connection.
729743
//-----------------------------------------------------------------------------
730744
int dpiConn__getRawTDO(dpiConn *conn, dpiError *error)
731745
{
@@ -2126,6 +2140,43 @@ int dpiConn_newEnqOptions(dpiConn *conn, dpiEnqOptions **options)
21262140
}
21272141

21282142

2143+
//-----------------------------------------------------------------------------
2144+
// dpiConn_newJson() [PUBLIC]
2145+
// Create a new JSON object and return it.
2146+
//-----------------------------------------------------------------------------
2147+
int dpiConn_newJson(dpiConn *conn, dpiJson **json)
2148+
{
2149+
dpiError error;
2150+
int status;
2151+
2152+
if (dpiConn__check(conn, __func__, &error) < 0)
2153+
return dpiGen__endPublicFn(conn, DPI_FAILURE, &error);
2154+
DPI_CHECK_PTR_NOT_NULL(conn, json);
2155+
status = dpiJson__allocate(conn, json, &error);
2156+
return dpiGen__endPublicFn(conn, status, &error);
2157+
}
2158+
2159+
2160+
//-----------------------------------------------------------------------------
2161+
// dpiConn_newJsonQueue() [PUBLIC]
2162+
// Create a new AQ queue object with JSON payload and return it.
2163+
//-----------------------------------------------------------------------------
2164+
int dpiConn_newJsonQueue(dpiConn *conn, const char *name, uint32_t nameLength,
2165+
dpiQueue **queue)
2166+
{
2167+
dpiError error;
2168+
int status;
2169+
2170+
if (dpiConn__check(conn, __func__, &error) < 0)
2171+
return dpiGen__endPublicFn(conn, DPI_FAILURE, &error);
2172+
DPI_CHECK_PTR_AND_LENGTH(conn, name)
2173+
DPI_CHECK_PTR_NOT_NULL(conn, queue)
2174+
status = dpiQueue__allocate(conn, name, nameLength, NULL, queue, 1,
2175+
&error);
2176+
return dpiGen__endPublicFn(conn, status, &error);
2177+
}
2178+
2179+
21292180
//-----------------------------------------------------------------------------
21302181
// dpiConn_newTempLob() [PUBLIC]
21312182
// Create a new temporary LOB and return it.
@@ -2194,7 +2245,7 @@ int dpiConn_newQueue(dpiConn *conn, const char *name, uint32_t nameLength,
21942245
DPI_CHECK_PTR_AND_LENGTH(conn, name)
21952246
DPI_CHECK_PTR_NOT_NULL(conn, queue)
21962247
status = dpiQueue__allocate(conn, name, nameLength, payloadType, queue,
2197-
&error);
2248+
0, &error);
21982249
return dpiGen__endPublicFn(conn, status, &error);
21992250
}
22002251

src/dpiImpl.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,8 +1245,8 @@ typedef struct {
12451245
dpiMsgProps **props; // array of dpiMsgProps handles
12461246
void **handles; // array of OCI msg prop handles
12471247
void **instances; // array of instances
1248-
void **indicators; // array of indicators
1249-
int16_t *rawIndicators; // array of indicators (RAW queues)
1248+
void **indicators; // array of indicator pointers
1249+
int16_t *scalarIndicators; // array of scalar indicator buffers
12501250
void **msgIds; // array of OCI message ids
12511251
} dpiQueueBuffer;
12521252

@@ -1290,6 +1290,7 @@ struct dpiConn {
12901290
const char *releaseString; // cached release string or NULL
12911291
uint32_t releaseStringLength; // cached release string length or 0
12921292
void *rawTDO; // cached RAW TDO
1293+
void *jsonTDO; // cached JSON TDO
12931294
dpiVersionInfo versionInfo; // Oracle database version info
12941295
uint32_t commitMode; // commit mode (for two-phase commits)
12951296
uint16_t charsetId; // database character set ID
@@ -1495,6 +1496,7 @@ struct dpiMsgProps {
14951496
void *handle; // OCI message properties handle
14961497
dpiObject *payloadObj; // payload (object)
14971498
void *payloadRaw; // payload (RAW)
1499+
dpiJson *payloadJson; // payload (JSON)
14981500
void *msgIdRaw; // message ID (RAW)
14991501
};
15001502

@@ -1555,6 +1557,7 @@ struct dpiQueue {
15551557
dpiDeqOptions *deqOptions; // dequeue options
15561558
dpiEnqOptions *enqOptions; // enqueue options
15571559
dpiQueueBuffer buffer; // buffer area
1560+
int isJson; // is JSON payload?
15581561
};
15591562

15601563

@@ -1685,6 +1688,7 @@ int dpiConn__create(dpiConn *conn, const dpiContext *context,
16851688
const dpiCommonCreateParams *commonParams,
16861689
dpiConnCreateParams *createParams, dpiError *error);
16871690
void dpiConn__free(dpiConn *conn, dpiError *error);
1691+
int dpiConn__getJsonTDO(dpiConn *conn, dpiError *error);
16881692
int dpiConn__getRawTDO(dpiConn *conn, dpiError *error);
16891693
int dpiConn__getServerVersion(dpiConn *conn, int wantReleaseString,
16901694
dpiError *error);
@@ -1861,7 +1865,8 @@ void dpiSodaDocCursor__free(dpiSodaDocCursor *cursor, dpiError *error);
18611865
// definition of internal dpiQueue methods
18621866
//-----------------------------------------------------------------------------
18631867
int dpiQueue__allocate(dpiConn *conn, const char *name, uint32_t nameLength,
1864-
dpiObjectType *payloadType, dpiQueue **queue, dpiError *error);
1868+
dpiObjectType *payloadType, dpiQueue **queue, int isJson,
1869+
dpiError *error);
18651870
void dpiQueue__free(dpiQueue *queue, dpiError *error);
18661871

18671872

src/dpiMsgProps.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,23 @@ int dpiMsgProps_getPayload(dpiMsgProps *props, dpiObject **obj,
360360
}
361361

362362

363+
//-----------------------------------------------------------------------------
364+
// dpiMsgProps_getPayloadJson() [PUBLIC]
365+
// Get the JSON payload for the message (as a dpiJson).
366+
//-----------------------------------------------------------------------------
367+
int dpiMsgProps_getPayloadJson(dpiMsgProps *props, dpiJson **json)
368+
{
369+
dpiError error;
370+
371+
if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__,
372+
&error) < 0)
373+
return dpiGen__endPublicFn(props, DPI_FAILURE, &error);
374+
DPI_CHECK_PTR_NOT_NULL(props, json)
375+
*json = props->payloadJson;
376+
return dpiGen__endPublicFn(props, DPI_SUCCESS, &error);
377+
}
378+
379+
363380
//-----------------------------------------------------------------------------
364381
// dpiMsgProps_getPriority() [PUBLIC]
365382
// Return the priority of the message.
@@ -493,6 +510,27 @@ int dpiMsgProps_setPayloadBytes(dpiMsgProps *props, const char *value,
493510
}
494511

495512

513+
//-----------------------------------------------------------------------------
514+
// dpiMsgProps_setPayloadJson() [PUBLIC]
515+
// Set the payload for the message (as a JSON object).
516+
//-----------------------------------------------------------------------------
517+
int dpiMsgProps_setPayloadJson(dpiMsgProps *props, dpiJson *json)
518+
{
519+
dpiError error;
520+
if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__,
521+
&error) < 0)
522+
return dpiGen__endPublicFn(props, DPI_FAILURE, &error);
523+
if (dpiGen__checkHandle(json, DPI_HTYPE_JSON, "check json object",
524+
&error) < 0)
525+
return dpiGen__endPublicFn(props, DPI_FAILURE, &error);
526+
if (props->payloadJson)
527+
dpiGen__setRefCount(props->payloadJson, &error, -1);
528+
dpiGen__setRefCount(json, &error, 1);
529+
props->payloadJson = json;
530+
return dpiGen__endPublicFn(props, DPI_SUCCESS, &error);
531+
}
532+
533+
496534
//-----------------------------------------------------------------------------
497535
// dpiMsgProps_setPayloadObject() [PUBLIC]
498536
// Set the payload for the message (as an object).

0 commit comments

Comments
 (0)