0 | module Oracle.Statement
2 | import Control.Monad.Elin
3 | import Control.Monad.MCancel
4 | import Data.ByteString
5 | import Data.Linear.Ref1
6 | import Oracle.Connection
8 | import Oracle.FFI.Bind
9 | import Oracle.FFI.DateTime
10 | import Oracle.FFI.Statement
11 | import Oracle.Internal.Decode
12 | import Oracle.Internal.Hex
13 | import Oracle.Internal.Pointer
14 | import Oracle.Types.BindParameter
15 | import Oracle.Types.DateTime
16 | import Oracle.Types.Error
17 | import Oracle.Types.Value
30 | prepare : Connection -> String -> IO (Either OracleError Statement)
31 | prepare conn sql = do
32 | ptr <- primIO (prim__prepareStmt conn.ptr sql)
33 | case prim__nullAnyPtr ptr == 1 of
35 | lasterr <- getLastError
38 | pure (Right $
MkStatement ptr)
45 | release : Statement -> IO ()
47 | primIO (prim__releaseStmt stmt.ptr)
62 | withStatement : Connection -> String -> (Statement -> IO (Either OracleError a)) -> IO (Either OracleError a)
63 | withStatement conn sql action = do
64 | result <- runElinIO (withStatement' conn sql)
73 | assert_total $
idris_crash "Oracle.Connection.withStatement: \{show err}"
75 | acquire : Connection -> String -> F1 World (Either OracleError Statement)
77 | ioToF1 (prepare conn sql)
78 | use : Either OracleError Statement -> F1 World (Either OracleError a)
82 | ioToF1 (pure (Left err))
84 | ioToF1 (action stmt')
85 | cleanup : Either OracleError Statement -> F1' World
91 | ioToF1 (release stmt')
92 | withStatement' : Connection -> String -> Elin World [] (Either OracleError a)
93 | withStatement' conn sql =
94 | bracket (runIO (acquire conn sql))
95 | (\stmt => runIO (use stmt))
96 | (\stmt => runIO (cleanup stmt))
108 | execute : Statement -> IO (Either OracleError ())
110 | rc <- primIO (prim__executeStmt stmt.ptr)
115 | lasterr <- getLastError
116 | pure (Left lasterr)
144 | bindOne : Statement -> BindParameter -> IO (Either OracleError ())
145 | bindOne stmt param =
146 | case param.value of
148 | primIO (prim__bindNull stmt.ptr param.name)
151 | primIO (prim__bindString stmt.ptr param.name s)
154 | primIO (prim__bindDouble stmt.ptr param.name d)
156 | OracleBinaryFloat f =>
157 | primIO (prim__bindBinaryFloat stmt.ptr param.name f)
159 | OracleBinaryDouble d =>
160 | primIO (prim__bindBinaryDouble stmt.ptr param.name d)
163 | primIO (prim__bindBool stmt.ptr param.name (if b then 1 else 0))
166 | primIO (prim__bindRaw stmt.ptr param.name (hexEncode $
unpack b))
169 | primIO (prim__bindClob stmt.ptr param.name s)
172 | primIO (prim__bindBlob stmt.ptr param.name (toString b))
175 | primIO ( prim__bindDate stmt.ptr
185 | OracleTimestamp ts =>
186 | primIO ( prim__bindTimestamp stmt.ptr
194 | (cast ts.nanosecond)
197 | OracleTimestampTZ ts =>
198 | primIO ( prim__bindTimestampTZ stmt.ptr
206 | (cast ts.nanosecond)
207 | (cast ts.tzHourOffset)
208 | (cast ts.tzMinuteOffset)
211 | OracleIntervalYM iv =>
212 | primIO ( prim__bindIntervalYM stmt.ptr
218 | OracleIntervalDS iv =>
219 | primIO ( prim__bindIntervalDS stmt.ptr
225 | (cast iv.nanoseconds)
229 | finish : Int32 -> IO (Either OracleError ())
235 | lasterr <- getLastError
236 | pure (Left lasterr)
241 | bind : Statement -> List BindParameter -> IO (Either OracleError ())
244 | bind stmt (x :: xs) = do
245 | res <- bindOne stmt x
264 | fetchRow : Statement -> IO (Either OracleError (Maybe (List OracleValue)))
266 | rc <- primIO (prim__fetch stmt.ptr)
267 | case compare rc 0 of
269 | Left <$> getLastError
271 | pure (Right Nothing)
273 | count <- primIO (prim__columnCount stmt.ptr)
274 | row <- go count 0 []
283 | go : Int32 -> Int32 -> List OracleValue -> IO (Either OracleError (List OracleValue))
284 | go count index acc =
285 | case index >= count of
287 | pure (Right $
reverse acc)
289 | value <- decodeColumn stmt.ptr index
305 | fetchRaw : Statement -> IO (Either OracleError (List (List OracleValue)))
309 | loop : List (List OracleValue) -> IO (Either OracleError (List (List OracleValue)))
311 | row <- fetchRow stmt
316 | pure (Right $
reverse acc)
317 | Right (Just values) =>
318 | loop (values :: acc)
327 | query : Connection -> String -> List BindParameter -> IO (Either OracleError (List (List OracleValue)))
328 | query conn sql params =
329 | withStatement conn sql $
\stmt => do
330 | bound <- bind stmt params
335 | executed <- execute stmt