1
1
{-# LANGUAGE DerivingStrategies #-}
2
2
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3
3
{-# LANGUAGE ViewPatterns #-}
4
+ {-# LANGUAGE TypeApplications #-}
5
+ {-# LANGUAGE RankNTypes #-}
6
+ {-# LANGUAGE RecordWildCards #-}
7
+ {-# LANGUAGE ScopedTypeVariables #-}
4
8
5
9
module Database.Oracle.Simple.Queue (
6
10
DPIQueue (.. )
7
11
, DPIMsgProps (.. )
8
12
, DPIDeqOptions (.. )
9
13
, DPIEnqOptions (.. )
10
14
, DPIObjectType (.. )
11
- , ObjectType (.. )
12
15
, deqMany
13
16
, deqOne
14
17
, enqMany
15
18
, enqOne
16
19
, getDeqOptions
17
20
, getEnqOptions
18
21
, queueRelease
19
- , genJSONQueue
22
+ , genQueueJSON
23
+ , genQueueObject
20
24
, genMsgProps
21
25
, genQueue
22
26
, getMsgPropsNumOfAttempts
23
27
, getMsgPropsDelay
24
28
, getMsgPropsPayLoadBytes
25
29
, getMsgPropsPayLoadJson
30
+ , getMsgPropsPayLoadObject
26
31
, setMsgPropsPayLoadBytes
27
32
, setMsgPropsPayLoadJSON
33
+ , setMsgPropsPayLoadObject
34
+ , objectAppendElement
35
+ , getObjectElementByIdx
28
36
) where
29
37
30
38
import Foreign (alloca , withArray , withForeignPtr , nullPtr )
@@ -33,7 +41,10 @@ import Foreign.C.Types (CInt (..), CUInt (..))
33
41
import Foreign.Ptr (Ptr )
34
42
import Foreign.C.String
35
43
import Database.Oracle.Simple.Internal
44
+ import Database.Oracle.Simple.ToField
45
+ import Database.Oracle.Simple.FromField
36
46
import qualified Data.ByteString.Char8 as BSC
47
+ import Data.Proxy (Proxy (.. ))
37
48
38
49
newtype DPIQueue = DPIQueue (Ptr DPIQueue )
39
50
deriving (Show , Eq )
@@ -51,13 +62,6 @@ newtype DPIEnqOptions = DPIEnqOptions (Ptr DPIEnqOptions)
51
62
deriving (Show , Eq )
52
63
deriving newtype (Storable )
53
64
54
- newtype DPIObjectType = DPIObjectType (Ptr DPIObjectType )
55
- deriving (Show , Eq )
56
- deriving newtype (Storable )
57
-
58
- data ObjectType = JSON | Raw
59
- deriving (Show , Eq )
60
-
61
65
deqMany :: DPIQueue -> Int -> IO DPIMsgProps
62
66
deqMany dpiQueue numProps = do
63
67
alloca $ \ dpiMsgPropsPtr -> do
@@ -167,8 +171,8 @@ foreign import ccall unsafe "dpiQueue_release"
167
171
DPIQueue ->
168
172
IO CInt
169
173
170
- genJSONQueue :: Connection -> String -> IO DPIQueue
171
- genJSONQueue (Connection fptr) queueName = do
174
+ genQueueJSON :: Connection -> String -> IO DPIQueue
175
+ genQueueJSON (Connection fptr) queueName = do
172
176
withForeignPtr fptr $ \ conn -> do
173
177
alloca $ \ dpiQueuePtr -> do
174
178
withCStringLen queueName $ \ (queueNameC , fromIntegral -> queueNameLen) -> do
@@ -202,14 +206,20 @@ foreign import ccall unsafe "dpiConn_newMsgProps"
202
206
Ptr DPIMsgProps ->
203
207
IO CInt
204
208
205
- -- For now, Passing objectType will not work :( use setPayLoadType.
206
209
genQueue :: Connection -> String -> IO DPIQueue
207
210
genQueue (Connection fptr) queueName = do
208
211
withForeignPtr fptr $ \ conn -> do
209
212
alloca $ \ dpiQueuePtr -> do
210
213
withCStringLen queueName $ \ (queueNameC , fromIntegral -> queueNameLen) -> do
211
214
throwOracleError =<< dpiConn_newQueue conn queueNameC queueNameLen nullPtr dpiQueuePtr
212
- -- TODO: Accomodate ObjectType
215
+ peek dpiQueuePtr
216
+
217
+ genQueueObject :: Connection -> String -> DPIObjectType -> IO DPIQueue
218
+ genQueueObject (Connection fptr) queueName (DPIObjectType objectType) = do
219
+ withForeignPtr fptr $ \ conn -> do
220
+ alloca $ \ dpiQueuePtr -> do
221
+ withCStringLen queueName $ \ (queueNameC , fromIntegral -> queueNameLen) -> do
222
+ throwOracleError =<< dpiConn_newQueue conn queueNameC queueNameLen objectType dpiQueuePtr
213
223
peek dpiQueuePtr
214
224
215
225
foreign import ccall unsafe " dpiConn_newQueue"
@@ -221,7 +231,7 @@ foreign import ccall unsafe "dpiConn_newQueue"
221
231
-- | name Length
222
232
CUInt ->
223
233
-- | dpiObjectType *
224
- Ptr () ->
234
+ Ptr DPIObjectType ->
225
235
-- | dpiQueue **
226
236
Ptr DPIQueue ->
227
237
IO CInt
@@ -256,7 +266,6 @@ foreign import ccall unsafe "dpiMsgProps_getDelay"
256
266
Ptr CUInt ->
257
267
IO CInt
258
268
259
-
260
269
{-
261
270
This function internally calls getPayLoad which either returns payLoad in either Object or in bytes.
262
271
Hence, the result might be null.
@@ -271,13 +280,21 @@ getMsgPropsPayLoadBytes dpiMsgProps = do
271
280
if cStr == nullPtr
272
281
then return Nothing
273
282
else Just . BSC. pack <$> peekCString cStr
274
-
283
+
284
+ getMsgPropsPayLoadObject :: DPIMsgProps -> IO (Maybe DPIObject )
285
+ getMsgPropsPayLoadObject dpiMsgProps =
286
+ alloca $ \ dpiObjectPtr -> do
287
+ throwOracleError =<< dpiMsgProps_getPayload dpiMsgProps dpiObjectPtr nullPtr nullPtr
288
+ if dpiObjectPtr == nullPtr
289
+ then return Nothing
290
+ else Just <$> peek dpiObjectPtr
291
+
275
292
foreign import ccall unsafe " dpiMsgProps_getPayload"
276
293
dpiMsgProps_getPayload ::
277
294
-- | dpiMsgProps *
278
295
DPIMsgProps ->
279
296
-- | dpiObject **
280
- Ptr DPIObjectType ->
297
+ Ptr DPIObject ->
281
298
-- | const char ** value
282
299
Ptr CString ->
283
300
-- | valueLength
@@ -313,6 +330,18 @@ foreign import ccall unsafe "dpiMsgProps_setPayloadBytes"
313
330
CUInt ->
314
331
IO CInt
315
332
333
+ setMsgPropsPayLoadObject :: DPIMsgProps -> DPIObject -> IO ()
334
+ setMsgPropsPayLoadObject dpiMsgProps obj = do
335
+ throwOracleError =<< dpiMsgProps_setPayloadObject dpiMsgProps obj
336
+
337
+ foreign import ccall unsafe " dpiMsgProps_setPayloadObject"
338
+ dpiMsgProps_setPayloadObject ::
339
+ -- | dpiMsgProps *
340
+ DPIMsgProps ->
341
+ -- | dpiObject* obj
342
+ DPIObject ->
343
+ IO CInt
344
+
316
345
setMsgPropsPayLoadJSON :: DPIMsgProps -> DPIJson -> IO ()
317
346
setMsgPropsPayLoadJSON dpiMsgProps payLoadJson = do
318
347
throwOracleError =<< dpiMsgProps_setPayloadJson dpiMsgProps payLoadJson
@@ -324,3 +353,55 @@ foreign import ccall unsafe "dpiMsgProps_setPayloadJson"
324
353
-- | dpiJson *
325
354
DPIJson ->
326
355
IO CInt
356
+
357
+ objectAppendElement :: forall a . (ToField a ) => DPIObject -> a -> IO ()
358
+ objectAppendElement obj val = do
359
+ dataValue <- toField val
360
+ let dataIsNull = case dataValue of
361
+ AsNull -> 1
362
+ _ -> 0
363
+ alloca $ \ dpiDataPtr -> do
364
+ let dpiData = DPIData {.. }
365
+ poke dpiDataPtr (dpiData :: DPIData WriteBuffer )
366
+ throwOracleError =<<
367
+ dpiObject_appendElement
368
+ obj
369
+ (dpiNativeTypeToUInt (toDPINativeType (Proxy @ a )))
370
+ (dpiDataPtr :: Ptr (DPIData WriteBuffer ))
371
+
372
+ foreign import ccall unsafe " dpiObject_appendElement"
373
+ dpiObject_appendElement ::
374
+ -- | dpiObject *
375
+ DPIObject ->
376
+ -- | dpiNativeTypeNum
377
+ CUInt ->
378
+ -- | dpiData* val
379
+ Ptr (DPIData WriteBuffer ) ->
380
+ IO CInt
381
+
382
+ getObjectElementByIdx
383
+ :: forall a . (FromField a ) =>
384
+ DPIObject ->
385
+ Int ->
386
+ IO a
387
+ getObjectElementByIdx obj idx = do
388
+ alloca $ \ dpiDataPtr -> do
389
+ throwOracleError =<<
390
+ dpiObject_getElementExistsByIndex
391
+ obj
392
+ (CInt $ fromIntegral idx)
393
+ (dpiNativeTypeToUInt (fromDPINativeType (Proxy @ a )))
394
+ dpiDataPtr
395
+ readDPIDataBuffer (fromField @ a ) dpiDataPtr
396
+
397
+ foreign import ccall unsafe " dpiObject_getElementExistsByIndex"
398
+ dpiObject_getElementExistsByIndex ::
399
+ -- | dpiObject *
400
+ DPIObject ->
401
+ -- | int32_t index
402
+ CInt ->
403
+ -- | dpiNativeTypeNum
404
+ CUInt ->
405
+ -- | dpiData *
406
+ Ptr (DPIData ReadBuffer ) ->
407
+ IO CInt
0 commit comments