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.Pointer
13 | import Oracle.Types.BindParameter
14 | import Oracle.Types.DateTime
15 | import Oracle.Types.Error
16 | import Oracle.Types.Value
29 | prepare : Connection -> String -> IO (Either OracleError Statement)
30 | prepare conn sql = do
31 | ptr <- primIO (prim__prepareStmt conn.ptr sql)
32 | case prim__nullAnyPtr ptr == 1 of
34 | lasterr <- getLastError
37 | pure (Right $
MkStatement ptr)
44 | release : Statement -> IO ()
46 | primIO (prim__releaseStmt stmt.ptr)
61 | withStatement : Connection -> String -> (Statement -> IO (Either OracleError a)) -> IO (Either OracleError a)
62 | withStatement conn sql action = do
63 | result <- runElinIO (withStatement' conn sql)
72 | assert_total $
idris_crash "Oracle.Connection.withStatement: \{show err}"
74 | acquire : Connection -> String -> F1 World (Either OracleError Statement)
76 | ioToF1 (prepare conn sql)
77 | use : Either OracleError Statement -> F1 World (Either OracleError a)
81 | ioToF1 (pure (Left err))
83 | ioToF1 (action stmt')
84 | cleanup : Either OracleError Statement -> F1' World
90 | ioToF1 (release stmt')
91 | withStatement' : Connection -> String -> Elin World [] (Either OracleError a)
92 | withStatement' conn sql =
93 | bracket (runIO (acquire conn sql))
94 | (\stmt => runIO (use stmt))
95 | (\stmt => runIO (cleanup stmt))
107 | execute : Statement -> IO (Either OracleError ())
109 | rc <- primIO (prim__executeStmt stmt.ptr)
114 | lasterr <- getLastError
115 | pure (Left lasterr)
142 | bindOne : Statement -> BindParameter -> IO (Either OracleError ())
143 | bindOne stmt param =
144 | case param.value of
146 | primIO (prim__bindNull stmt.ptr param.name)
149 | primIO (prim__bindString stmt.ptr param.name s)
152 | primIO (prim__bindDouble stmt.ptr param.name d)
155 | primIO (prim__bindBool stmt.ptr param.name (if b then 1 else 0))
158 | primIO (prim__bindClob stmt.ptr param.name s)
161 | primIO (prim__bindBlob stmt.ptr param.name (toString b))
163 | OracleTimestamp ts =>
164 | primIO ( prim__bindTimestamp stmt.ptr
172 | (cast ts.nanosecond)
175 | OracleTimestampTZ ts =>
176 | primIO ( prim__bindTimestampTZ stmt.ptr
184 | (cast ts.nanosecond)
185 | (cast ts.tzHourOffset)
186 | (cast ts.tzMinuteOffset)
189 | OracleIntervalYM iv =>
190 | primIO ( prim__bindIntervalYM stmt.ptr
196 | OracleIntervalDS iv =>
197 | primIO ( prim__bindIntervalDS stmt.ptr
203 | (cast iv.nanoseconds)
207 | finish : Int32 -> IO (Either OracleError ())
213 | lasterr <- getLastError
214 | pure (Left lasterr)
219 | bind : Statement -> List BindParameter -> IO (Either OracleError ())
222 | bind stmt (x :: xs) = do
223 | res <- bindOne stmt x
242 | fetchRow : Statement -> IO (Either OracleError (Maybe (List OracleValue)))
244 | rc <- primIO (prim__fetch stmt.ptr)
245 | case compare rc 0 of
247 | Left <$> getLastError
249 | pure (Right Nothing)
251 | count <- primIO (prim__columnCount stmt.ptr)
252 | row <- go count 0 []
261 | go : Int32 -> Int32 -> List OracleValue -> IO (Either OracleError (List OracleValue))
262 | go count index acc =
263 | case index >= count of
265 | pure (Right $
reverse acc)
267 | value <- decodeColumn stmt.ptr index
283 | fetchRaw : Statement -> IO (Either OracleError (List (List OracleValue)))
287 | loop : List (List OracleValue) -> IO (Either OracleError (List (List OracleValue)))
289 | row <- fetchRow stmt
294 | pure (Right $
reverse acc)
295 | Right (Just values) =>
296 | loop (values :: acc)
305 | query : Connection -> String -> List BindParameter -> IO (Either OracleError (List (List OracleValue)))
306 | query conn sql params =
307 | withStatement conn sql $
\stmt => do
308 | bound <- bind stmt params
313 | executed <- execute stmt