0 | module Oracle.Internal.Decode
2 | import Control.Monad.Elin
3 | import Control.Monad.MCancel
4 | import Data.ByteString
5 | import Data.Linear.Ref1
7 | import Oracle.FFI.Data
8 | import Oracle.FFI.DateTime
9 | import Oracle.FFI.Lob
10 | import Oracle.FFI.QueryInfo
11 | import Oracle.FFI.Statement
12 | import Oracle.Internal.QueryInfo
13 | import Oracle.Types.ColumnInfo
14 | import Oracle.Types.DateTime
15 | import Oracle.Types.OracleType
16 | import Oracle.Types.Value
17 | import Oracle.Types.Error
28 | getColumnInfo : AnyPtr -> Int32 -> IO (Either OracleError ColumnInfo)
29 | getColumnInfo stmt column =
30 | withQueryInfo stmt column $
\info => do
31 | name <- primIO (prim__queryInfoName info)
32 | tynum <- primIO (prim__queryInfoType info)
33 | size <- primIO (prim__queryInfoSize info)
34 | nullable <- primIO (prim__queryInfoNullable info)
38 | (fromOracleTypeNum tynum)
52 | decodeColumn : AnyPtr -> Int32 -> IO (Either OracleError OracleValue)
53 | decodeColumn stmt column = do
54 | inforesult <- getColumnInfo stmt column
59 | dataptr <- primIO (prim__columnValue stmt column)
60 | case prim__nullAnyPtr dataptr == 1 of
62 | lasterr <- getLastError
65 | isnull <- primIO (prim__dataIsNull dataptr)
68 | pure (Right OracleNull)
70 | case info.oracletype of
71 | OracleTypeVarchar =>
72 | Right . OracleString <$>
73 | primIO (prim__dataString dataptr)
75 | Right . OracleNumber <$>
76 | primIO (prim__dataDouble dataptr)
78 | Right . OracleBlob . fromString <$>
79 | primIO (prim__dataString dataptr)
80 | OracleTypeTimestamp => do
81 | ts <- primIO (prim__dataTimestamp dataptr)
86 | !(primIO (prim__timestampYear ts))
87 | !(primIO (prim__timestampMonth ts))
88 | !(primIO (prim__timestampDay ts))
89 | !(primIO (prim__timestampHour ts))
90 | !(primIO (prim__timestampMinute ts))
91 | !(primIO (prim__timestampSecond ts))
92 | !(primIO (prim__timestampNanosecond ts))
93 | OracleTypeTimestampTZ => do
94 | ts <- primIO (prim__dataTimestamp dataptr)
99 | !(primIO (prim__timestampYear ts))
100 | !(primIO (prim__timestampMonth ts))
101 | !(primIO (prim__timestampDay ts))
102 | !(primIO (prim__timestampHour ts))
103 | !(primIO (prim__timestampMinute ts))
104 | !(primIO (prim__timestampSecond ts))
105 | !(primIO (prim__timestampNanosecond ts))
106 | !(primIO (prim__timestampTZHour ts))
107 | !(primIO (prim__timestampTZMinute ts))
108 | OracleTypeIntervalYM => do
109 | iv <- primIO (prim__dataIntervalYM dataptr)
114 | !(primIO (prim__intervalYMYears iv))
115 | !(primIO (prim__intervalYMMonths iv))
116 | OracleTypeIntervalDS => do
117 | iv <- primIO (prim__dataIntervalDS dataptr)
122 | !(primIO (prim__intervalDSDays iv))
123 | !(primIO (prim__intervalDSHours iv))
124 | !(primIO (prim__intervalDSMinutes iv))
125 | !(primIO (prim__intervalDSSeconds iv))
126 | !(primIO (prim__intervalDSNanoseconds iv))
127 | OracleTypeBlob => do
128 | result <- runElinIO (withDataPtrAndOracleType dataptr OracleTypeBlob)
135 | pure (Right value')
137 | assert_total $
idris_crash "Oracle.Internal.Decode.decodeColumn: \{show err}"
138 | OracleTypeClob => do
139 | result <- runElinIO (withDataPtrAndOracleType dataptr OracleTypeClob)
146 | pure (Right value')
148 | assert_total $
idris_crash "Oracle.Internal.Decode.decodeColumn: \{show err}"
149 | OracleTypeBoolean => do
150 | b <- primIO (prim__dataBool dataptr)
153 | pure (Right $
OracleBool False)
155 | pure (Right $
OracleBool True)
161 | "Unsupported BOOLEAN: \{show n}"
162 | "Oracle.Internal.Decode.decodeColumn"
164 | OracleTypeUnknown n =>
169 | ("Unsupported Oracle type: " ++ show n)
170 | "Oracle.Internal.Decode.decodeColumn"
173 | acquire : AnyPtr -> F1 World AnyPtr
175 | ioToF1 (primIO (prim__dataLob dataptr))
176 | use : AnyPtr -> OracleType -> F1 World (Either OracleError OracleValue)
177 | use ptr oracletype =
180 | ioToF1 ( do case prim__nullAnyPtr ptr == 1 of
182 | lasterr <- getLastError
183 | pure (Left lasterr)
185 | size <- primIO (prim__lobSize ptr)
188 | lasterr <- getLastError
189 | pure (Left lasterr)
191 | bytes <- primIO (prim__lobRead ptr 1 size)
192 | pure (Right $
OracleBlob $
fromString bytes)
195 | ioToF1 ( do case prim__nullAnyPtr ptr == 1 of
197 | lasterr <- getLastError
198 | pure (Left lasterr)
200 | text <- primIO (prim__clobRead ptr)
201 | pure (Right $
OracleClob text)
208 | "Unsupported type: \{show ty}"
209 | "Oracle.Internal.Decode.decodeColumn.use"
212 | release : AnyPtr -> F1' World
214 | ioToF1 (primIO (prim__lobRelease ptr))
215 | withDataPtrAndOracleType : AnyPtr -> OracleType -> Elin World [] (Either OracleError OracleValue)
216 | withDataPtrAndOracleType dataptr oracletype =
217 | bracket (runIO (acquire dataptr))
218 | (\ptr => runIO (use ptr oracletype))
219 | (\ptr => runIO (release ptr))