0 | module Oracle.Internal.QueryInfo
 1 |
 2 | import Control.Monad.Elin
 3 | import Control.Monad.MCancel
 4 | import Data.Linear.Ref1
 5 | import Oracle.Error
 6 | import Oracle.FFI.QueryInfo
 7 | import Oracle.Types.ColumnInfo
 8 | import Oracle.Types.Error
 9 | import Oracle.Types.OracleType
10 |
11 | ||| Acquire a dpiQueryInfo structure, execute an action, and guarantee cleanup.
12 | |||
13 | export
14 | withQueryInfo : AnyPtr -> Int32 -> (AnyPtr -> IO a) -> IO (Either OracleError a)
15 | withQueryInfo stmt column action = do
16 |   result <- runElinIO (withQueryInfo' stmt column)
17 |   case result of
18 |     Right value =>
19 |       case value of
20 |         Left err     =>
21 |           pure (Left err)
22 |         Right value' =>
23 |           pure (Right value')
24 |     Left err    =>
25 |       assert_total $ idris_crash "Data.Oracle.Internal.withQueryInfo: \{show err}"
26 |   where
27 |     acquire : AnyPtr -> Int32 -> F1 World AnyPtr
28 |     acquire stmt column =
29 |       ioToF1 (primIO (prim__queryInfo stmt column))
30 |     use : AnyPtr -> F1 World (Either OracleError a)
31 |     use ptr =
32 |       ioToF1 ( do case prim__nullAnyPtr ptr == 1 of
33 |                     True  => do
34 |                       lasterr <- getLastError
35 |                       pure (Left lasterr)
36 |                     False => do
37 |                       ptr' <- action ptr
38 |                       pure (Right ptr')
39 |              )
40 |     release : AnyPtr -> F1' World
41 |     release ptr =
42 |       ioToF1 (primIO (prim__queryInfoFree ptr))
43 |     withQueryInfo' : AnyPtr -> Int32 -> Elin World [] (Either OracleError a)
44 |     withQueryInfo' stmt column =
45 |       bracket (runIO (acquire stmt column))
46 |               (\ptr => runIO (use ptr))
47 |               (\ptr => runIO (release ptr))
48 |