{-# LANGUAGE DeriveDataTypeable, ForeignFunctionInterface, RecordWildCards #-}
module Database.MySQL.Base
(
ConnectInfo(..)
, SSLInfo(..)
, Seconds
, Protocol(..)
, Option(..)
, defaultConnectInfo
, defaultSSLInfo
, Connection
, Result
, Type(..)
, Row
, MySQLError(errFunction, errNumber, errMessage)
, connect
, close
, autocommit
, ping
, changeUser
, selectDB
, setCharacterSet
, threadId
, serverInfo
, hostInfo
, protocolInfo
, characterSet
, sslCipher
, serverStatus
, query
, insertID
, escape
, fieldCount
, affectedRows
, isResultValid
, freeResult
, storeResult
, useResult
, fetchRow
, fetchFields
, dataSeek
, rowSeek
, rowTell
, nextResult
, commit
, rollback
, clientInfo
, clientVersion
, initLibrary
, initThread
, endThread
) where
import Control.Applicative ((<$>), (<*>))
import Control.Concurrent (rtsSupportsBoundThreads, runInBoundThread)
import Control.Exception (Exception, throw)
import Control.Monad (forM_, unless, when)
import Data.ByteString.Char8 ()
import Data.ByteString.Internal (ByteString, create, createAndTrim, memcpy)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.IORef (IORef, atomicModifyIORef, newIORef, readIORef, writeIORef)
import Data.Int (Int64)
import Data.List (foldl')
import Data.Typeable (Typeable)
import Data.Word (Word, Word16, Word64)
import Database.MySQL.Base.C
import Database.MySQL.Base.Types
import Foreign.C.String (CString, peekCString, withCString)
import Foreign.C.Types (CULong)
import Foreign.Concurrent (newForeignPtr)
import Foreign.ForeignPtr hiding (newForeignPtr)
import Foreign.Marshal.Array (peekArray)
import Foreign.Ptr (Ptr, castPtr, nullPtr)
import System.IO.Unsafe (unsafePerformIO)
import System.Mem.Weak (Weak, deRefWeak, mkWeakPtr)
data ConnectInfo = ConnectInfo {
ConnectInfo -> String
connectHost :: String
, ConnectInfo -> Word16
connectPort :: Word16
, ConnectInfo -> String
connectUser :: String
, ConnectInfo -> String
connectPassword :: String
, ConnectInfo -> String
connectDatabase :: String
, ConnectInfo -> [Option]
connectOptions :: [Option]
, ConnectInfo -> String
connectPath :: FilePath
, ConnectInfo -> Maybe SSLInfo
connectSSL :: Maybe SSLInfo
} deriving (ConnectInfo -> ConnectInfo -> Bool
(ConnectInfo -> ConnectInfo -> Bool)
-> (ConnectInfo -> ConnectInfo -> Bool) -> Eq ConnectInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ConnectInfo -> ConnectInfo -> Bool
$c/= :: ConnectInfo -> ConnectInfo -> Bool
== :: ConnectInfo -> ConnectInfo -> Bool
$c== :: ConnectInfo -> ConnectInfo -> Bool
Eq, ReadPrec [ConnectInfo]
ReadPrec ConnectInfo
Int -> ReadS ConnectInfo
ReadS [ConnectInfo]
(Int -> ReadS ConnectInfo)
-> ReadS [ConnectInfo]
-> ReadPrec ConnectInfo
-> ReadPrec [ConnectInfo]
-> Read ConnectInfo
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ConnectInfo]
$creadListPrec :: ReadPrec [ConnectInfo]
readPrec :: ReadPrec ConnectInfo
$creadPrec :: ReadPrec ConnectInfo
readList :: ReadS [ConnectInfo]
$creadList :: ReadS [ConnectInfo]
readsPrec :: Int -> ReadS ConnectInfo
$creadsPrec :: Int -> ReadS ConnectInfo
Read, Int -> ConnectInfo -> ShowS
[ConnectInfo] -> ShowS
ConnectInfo -> String
(Int -> ConnectInfo -> ShowS)
-> (ConnectInfo -> String)
-> ([ConnectInfo] -> ShowS)
-> Show ConnectInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ConnectInfo] -> ShowS
$cshowList :: [ConnectInfo] -> ShowS
show :: ConnectInfo -> String
$cshow :: ConnectInfo -> String
showsPrec :: Int -> ConnectInfo -> ShowS
$cshowsPrec :: Int -> ConnectInfo -> ShowS
Show, Typeable)
data SSLInfo = SSLInfo {
SSLInfo -> String
sslKey :: FilePath
, SSLInfo -> String
sslCert :: FilePath
, SSLInfo -> String
sslCA :: FilePath
, SSLInfo -> String
sslCAPath :: FilePath
, SSLInfo -> String
sslCiphers :: String
} deriving (SSLInfo -> SSLInfo -> Bool
(SSLInfo -> SSLInfo -> Bool)
-> (SSLInfo -> SSLInfo -> Bool) -> Eq SSLInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SSLInfo -> SSLInfo -> Bool
$c/= :: SSLInfo -> SSLInfo -> Bool
== :: SSLInfo -> SSLInfo -> Bool
$c== :: SSLInfo -> SSLInfo -> Bool
Eq, ReadPrec [SSLInfo]
ReadPrec SSLInfo
Int -> ReadS SSLInfo
ReadS [SSLInfo]
(Int -> ReadS SSLInfo)
-> ReadS [SSLInfo]
-> ReadPrec SSLInfo
-> ReadPrec [SSLInfo]
-> Read SSLInfo
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SSLInfo]
$creadListPrec :: ReadPrec [SSLInfo]
readPrec :: ReadPrec SSLInfo
$creadPrec :: ReadPrec SSLInfo
readList :: ReadS [SSLInfo]
$creadList :: ReadS [SSLInfo]
readsPrec :: Int -> ReadS SSLInfo
$creadsPrec :: Int -> ReadS SSLInfo
Read, Int -> SSLInfo -> ShowS
[SSLInfo] -> ShowS
SSLInfo -> String
(Int -> SSLInfo -> ShowS)
-> (SSLInfo -> String) -> ([SSLInfo] -> ShowS) -> Show SSLInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SSLInfo] -> ShowS
$cshowList :: [SSLInfo] -> ShowS
show :: SSLInfo -> String
$cshow :: SSLInfo -> String
showsPrec :: Int -> SSLInfo -> ShowS
$cshowsPrec :: Int -> SSLInfo -> ShowS
Show, Typeable)
data MySQLError = ConnectionError {
MySQLError -> String
errFunction :: String
, MySQLError -> Int
errNumber :: Int
, MySQLError -> String
errMessage :: String
} | ResultError {
errFunction :: String
, errNumber :: Int
, errMessage :: String
} deriving (MySQLError -> MySQLError -> Bool
(MySQLError -> MySQLError -> Bool)
-> (MySQLError -> MySQLError -> Bool) -> Eq MySQLError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MySQLError -> MySQLError -> Bool
$c/= :: MySQLError -> MySQLError -> Bool
== :: MySQLError -> MySQLError -> Bool
$c== :: MySQLError -> MySQLError -> Bool
Eq, Int -> MySQLError -> ShowS
[MySQLError] -> ShowS
MySQLError -> String
(Int -> MySQLError -> ShowS)
-> (MySQLError -> String)
-> ([MySQLError] -> ShowS)
-> Show MySQLError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MySQLError] -> ShowS
$cshowList :: [MySQLError] -> ShowS
show :: MySQLError -> String
$cshow :: MySQLError -> String
showsPrec :: Int -> MySQLError -> ShowS
$cshowsPrec :: Int -> MySQLError -> ShowS
Show, Typeable)
instance Exception MySQLError
data Connection = Connection {
Connection -> ForeignPtr MYSQL
connFP :: ForeignPtr MYSQL
, Connection -> IO ()
connClose :: IO ()
, Connection -> IORef (Maybe (Weak Result))
connResult :: IORef (Maybe (Weak Result))
} deriving (Typeable)
data Result = Result {
Result -> ForeignPtr MYSQL_RES
resFP :: ForeignPtr MYSQL_RES
, Result -> Int
resFields :: {-# UNPACK #-} !Int
, Result -> Connection
resConnection :: Connection
, Result -> IORef Bool
resValid :: IORef Bool
, Result -> Ptr MYSQL_RES -> IO (Ptr Field)
resFetchFields :: Ptr MYSQL_RES -> IO (Ptr Field)
, Result -> Ptr MYSQL_RES -> IO MYSQL_ROW
resFetchRow :: Ptr MYSQL_RES -> IO MYSQL_ROW
, Result -> Ptr MYSQL_RES -> IO (Ptr CULong)
resFetchLengths :: Ptr MYSQL_RES -> IO (Ptr CULong)
, Result -> Ptr MYSQL_RES -> IO ()
resFreeResult :: Ptr MYSQL_RES -> IO ()
} | EmptyResult
deriving (Typeable)
newtype Row = Row MYSQL_ROW_OFFSET
deriving (Typeable)
defaultConnectInfo :: ConnectInfo
defaultConnectInfo :: ConnectInfo
defaultConnectInfo = ConnectInfo :: String
-> Word16
-> String
-> String
-> String
-> [Option]
-> String
-> Maybe SSLInfo
-> ConnectInfo
ConnectInfo {
connectHost :: String
connectHost = String
"localhost"
, connectPort :: Word16
connectPort = Word16
3306
, connectUser :: String
connectUser = String
"root"
, connectPassword :: String
connectPassword = String
""
, connectDatabase :: String
connectDatabase = String
"test"
, connectOptions :: [Option]
connectOptions = [String -> Option
CharsetName String
"utf8"]
, connectPath :: String
connectPath = String
""
, connectSSL :: Maybe SSLInfo
connectSSL = Maybe SSLInfo
forall a. Maybe a
Nothing
}
defaultSSLInfo :: SSLInfo
defaultSSLInfo :: SSLInfo
defaultSSLInfo = SSLInfo :: String -> String -> String -> String -> String -> SSLInfo
SSLInfo {
sslKey :: String
sslKey = String
""
, sslCert :: String
sslCert = String
""
, sslCA :: String
sslCA = String
""
, sslCAPath :: String
sslCAPath = String
""
, sslCiphers :: String
sslCiphers = String
""
}
connect :: ConnectInfo -> IO Connection
connect :: ConnectInfo -> IO Connection
connect ConnectInfo{String
[Option]
Maybe SSLInfo
Word16
connectSSL :: Maybe SSLInfo
connectPath :: String
connectOptions :: [Option]
connectDatabase :: String
connectPassword :: String
connectUser :: String
connectPort :: Word16
connectHost :: String
connectSSL :: ConnectInfo -> Maybe SSLInfo
connectPath :: ConnectInfo -> String
connectOptions :: ConnectInfo -> [Option]
connectDatabase :: ConnectInfo -> String
connectPassword :: ConnectInfo -> String
connectUser :: ConnectInfo -> String
connectPort :: ConnectInfo -> Word16
connectHost :: ConnectInfo -> String
..} = do
IORef Bool
closed <- Bool -> IO (IORef Bool)
forall a. a -> IO (IORef a)
newIORef Bool
False
Ptr MYSQL
ptr0 <- Ptr MYSQL -> IO (Ptr MYSQL)
mysql_init Ptr MYSQL
forall a. Ptr a
nullPtr
case Maybe SSLInfo
connectSSL of
Maybe SSLInfo
Nothing -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just SSLInfo{String
sslCiphers :: String
sslCAPath :: String
sslCA :: String
sslCert :: String
sslKey :: String
sslCiphers :: SSLInfo -> String
sslCAPath :: SSLInfo -> String
sslCA :: SSLInfo -> String
sslCert :: SSLInfo -> String
sslKey :: SSLInfo -> String
..} -> String -> (CString -> IO ()) -> IO ()
forall a. String -> (CString -> IO a) -> IO a
withString String
sslKey ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \CString
ckey ->
String -> (CString -> IO ()) -> IO ()
forall a. String -> (CString -> IO a) -> IO a
withString String
sslCert ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \CString
ccert ->
String -> (CString -> IO ()) -> IO ()
forall a. String -> (CString -> IO a) -> IO a
withString String
sslCA ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \CString
cca ->
String -> (CString -> IO ()) -> IO ()
forall a. String -> (CString -> IO a) -> IO a
withString String
sslCAPath ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \CString
ccapath ->
String -> (CString -> IO ()) -> IO ()
forall a. String -> (CString -> IO a) -> IO a
withString String
sslCiphers ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \CString
ccipher ->
Ptr MYSQL
-> CString -> CString -> CString -> CString -> CString -> IO MyBool
mysql_ssl_set Ptr MYSQL
ptr0 CString
ckey CString
ccert CString
cca CString
ccapath CString
ccipher
IO MyBool -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
[Option] -> (Option -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Option]
connectOptions ((Option -> IO ()) -> IO ()) -> (Option -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Option
opt -> do
CInt
r <- Ptr MYSQL -> Option -> IO CInt
mysql_options Ptr MYSQL
ptr0 Option
opt
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (CInt
r CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
== CInt
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> Ptr MYSQL -> IO ()
forall a. String -> Ptr MYSQL -> IO a
connectionError_ String
"connect" Ptr MYSQL
ptr0
let flags :: CULong
flags = (CULong -> CULong -> CULong) -> CULong -> [CULong] -> CULong
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' CULong -> CULong -> CULong
forall a. Num a => a -> a -> a
(+) CULong
0 ([CULong] -> CULong)
-> ([Option] -> [CULong]) -> [Option] -> CULong
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Option -> CULong) -> [Option] -> [CULong]
forall a b. (a -> b) -> [a] -> [b]
map Option -> CULong
toConnectFlag ([Option] -> CULong) -> [Option] -> CULong
forall a b. (a -> b) -> a -> b
$ [Option]
connectOptions
Ptr MYSQL
ptr <- String -> (CString -> IO (Ptr MYSQL)) -> IO (Ptr MYSQL)
forall a. String -> (CString -> IO a) -> IO a
withString String
connectHost ((CString -> IO (Ptr MYSQL)) -> IO (Ptr MYSQL))
-> (CString -> IO (Ptr MYSQL)) -> IO (Ptr MYSQL)
forall a b. (a -> b) -> a -> b
$ \CString
chost ->
String -> (CString -> IO (Ptr MYSQL)) -> IO (Ptr MYSQL)
forall a. String -> (CString -> IO a) -> IO a
withString String
connectUser ((CString -> IO (Ptr MYSQL)) -> IO (Ptr MYSQL))
-> (CString -> IO (Ptr MYSQL)) -> IO (Ptr MYSQL)
forall a b. (a -> b) -> a -> b
$ \CString
cuser ->
String -> (CString -> IO (Ptr MYSQL)) -> IO (Ptr MYSQL)
forall a. String -> (CString -> IO a) -> IO a
withString String
connectPassword ((CString -> IO (Ptr MYSQL)) -> IO (Ptr MYSQL))
-> (CString -> IO (Ptr MYSQL)) -> IO (Ptr MYSQL)
forall a b. (a -> b) -> a -> b
$ \CString
cpass ->
String -> (CString -> IO (Ptr MYSQL)) -> IO (Ptr MYSQL)
forall a. String -> (CString -> IO a) -> IO a
withString String
connectDatabase ((CString -> IO (Ptr MYSQL)) -> IO (Ptr MYSQL))
-> (CString -> IO (Ptr MYSQL)) -> IO (Ptr MYSQL)
forall a b. (a -> b) -> a -> b
$ \CString
cdb ->
String -> (CString -> IO (Ptr MYSQL)) -> IO (Ptr MYSQL)
forall a. String -> (CString -> IO a) -> IO a
withString String
connectPath ((CString -> IO (Ptr MYSQL)) -> IO (Ptr MYSQL))
-> (CString -> IO (Ptr MYSQL)) -> IO (Ptr MYSQL)
forall a b. (a -> b) -> a -> b
$ \CString
cpath ->
Ptr MYSQL
-> CString
-> CString
-> CString
-> CString
-> CInt
-> CString
-> CULong
-> IO (Ptr MYSQL)
mysql_real_connect Ptr MYSQL
ptr0 CString
chost CString
cuser CString
cpass CString
cdb
(Word16 -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
connectPort) CString
cpath CULong
flags
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Ptr MYSQL
ptr Ptr MYSQL -> Ptr MYSQL -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr MYSQL
forall a. Ptr a
nullPtr) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
String -> Ptr MYSQL -> IO ()
forall a. String -> Ptr MYSQL -> IO a
connectionError_ String
"connect" Ptr MYSQL
ptr0
IORef (Maybe (Weak Result))
res <- Maybe (Weak Result) -> IO (IORef (Maybe (Weak Result)))
forall a. a -> IO (IORef a)
newIORef Maybe (Weak Result)
forall a. Maybe a
Nothing
let realClose :: IO ()
realClose = do
IORef (Maybe (Weak Result)) -> IO ()
cleanupConnResult IORef (Maybe (Weak Result))
res
Bool
wasClosed <- IORef Bool -> (Bool -> (Bool, Bool)) -> IO Bool
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef IORef Bool
closed ((Bool -> (Bool, Bool)) -> IO Bool)
-> (Bool -> (Bool, Bool)) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \Bool
prev -> (Bool
True, Bool
prev)
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
wasClosed (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr MYSQL -> IO ()
mysql_close Ptr MYSQL
ptr
let myRunInBoundThread :: IO a -> IO a
myRunInBoundThread = if Bool
rtsSupportsBoundThreads then IO a -> IO a
forall a. IO a -> IO a
runInBoundThread else IO a -> IO a
forall a. a -> a
id
ForeignPtr MYSQL
fp <- Ptr MYSQL -> IO () -> IO (ForeignPtr MYSQL)
forall a. Ptr a -> IO () -> IO (ForeignPtr a)
newForeignPtr Ptr MYSQL
ptr (IO () -> IO ()
forall a. IO a -> IO a
myRunInBoundThread (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ IO ()
initThread IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO ()
realClose)
Connection -> IO Connection
forall (m :: * -> *) a. Monad m => a -> m a
return Connection :: ForeignPtr MYSQL
-> IO () -> IORef (Maybe (Weak Result)) -> Connection
Connection {
connFP :: ForeignPtr MYSQL
connFP = ForeignPtr MYSQL
fp
, connClose :: IO ()
connClose = IO ()
realClose
, connResult :: IORef (Maybe (Weak Result))
connResult = IORef (Maybe (Weak Result))
res
}
cleanupConnResult :: IORef (Maybe (Weak Result)) -> IO ()
cleanupConnResult :: IORef (Maybe (Weak Result)) -> IO ()
cleanupConnResult IORef (Maybe (Weak Result))
res = do
Maybe (Weak Result)
prev <- IORef (Maybe (Weak Result)) -> IO (Maybe (Weak Result))
forall a. IORef a -> IO a
readIORef IORef (Maybe (Weak Result))
res
case Maybe (Weak Result)
prev of
Maybe (Weak Result)
Nothing -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just Weak Result
w -> IO () -> (Result -> IO ()) -> Maybe Result -> IO ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) Result -> IO ()
freeResult (Maybe Result -> IO ()) -> IO (Maybe Result) -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Weak Result -> IO (Maybe Result)
forall v. Weak v -> IO (Maybe v)
deRefWeak Weak Result
w
close :: Connection -> IO ()
close :: Connection -> IO ()
close = Connection -> IO ()
connClose
{-# INLINE close #-}
ping :: Connection -> IO ()
ping :: Connection -> IO ()
ping Connection
conn = Connection -> (Ptr MYSQL -> IO ()) -> IO ()
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO ()) -> IO ()) -> (Ptr MYSQL -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr -> Ptr MYSQL -> IO CInt
mysql_ping Ptr MYSQL
ptr IO CInt -> (CInt -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Connection -> CInt -> IO ()
forall a. (Eq a, Num a) => String -> Connection -> a -> IO ()
check String
"ping" Connection
conn
threadId :: Connection -> IO Word
threadId :: Connection -> IO Word
threadId Connection
conn = CULong -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CULong -> Word) -> IO CULong -> IO Word
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Connection -> (Ptr MYSQL -> IO CULong) -> IO CULong
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn Ptr MYSQL -> IO CULong
mysql_thread_id
serverInfo :: Connection -> IO String
serverInfo :: Connection -> IO String
serverInfo Connection
conn = Connection -> (Ptr MYSQL -> IO String) -> IO String
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO String) -> IO String)
-> (Ptr MYSQL -> IO String) -> IO String
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr ->
CString -> IO String
peekCString (CString -> IO String) -> IO CString -> IO String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr MYSQL -> IO CString
mysql_get_server_info Ptr MYSQL
ptr
hostInfo :: Connection -> IO String
hostInfo :: Connection -> IO String
hostInfo Connection
conn = Connection -> (Ptr MYSQL -> IO String) -> IO String
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO String) -> IO String)
-> (Ptr MYSQL -> IO String) -> IO String
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr ->
CString -> IO String
peekCString (CString -> IO String) -> IO CString -> IO String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr MYSQL -> IO CString
mysql_get_host_info Ptr MYSQL
ptr
protocolInfo :: Connection -> IO Word
protocolInfo :: Connection -> IO Word
protocolInfo Connection
conn = Connection -> (Ptr MYSQL -> IO Word) -> IO Word
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO Word) -> IO Word)
-> (Ptr MYSQL -> IO Word) -> IO Word
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr ->
CUInt -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CUInt -> Word) -> IO CUInt -> IO Word
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr MYSQL -> IO CUInt
mysql_get_proto_info Ptr MYSQL
ptr
setCharacterSet :: Connection -> String -> IO ()
setCharacterSet :: Connection -> String -> IO ()
setCharacterSet Connection
conn String
cs =
String -> (CString -> IO ()) -> IO ()
forall a. String -> (CString -> IO a) -> IO a
withCString String
cs ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \CString
ccs ->
Connection -> (Ptr MYSQL -> IO ()) -> IO ()
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO ()) -> IO ()) -> (Ptr MYSQL -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr ->
Ptr MYSQL -> CString -> IO CInt
mysql_set_character_set Ptr MYSQL
ptr CString
ccs IO CInt -> (CInt -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Connection -> CInt -> IO ()
forall a. (Eq a, Num a) => String -> Connection -> a -> IO ()
check String
"setCharacterSet" Connection
conn
characterSet :: Connection -> IO String
characterSet :: Connection -> IO String
characterSet Connection
conn = Connection -> (Ptr MYSQL -> IO String) -> IO String
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO String) -> IO String)
-> (Ptr MYSQL -> IO String) -> IO String
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr ->
CString -> IO String
peekCString (CString -> IO String) -> IO CString -> IO String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr MYSQL -> IO CString
mysql_character_set_name Ptr MYSQL
ptr
sslCipher :: Connection -> IO (Maybe String)
sslCipher :: Connection -> IO (Maybe String)
sslCipher Connection
conn = Connection -> (Ptr MYSQL -> IO (Maybe String)) -> IO (Maybe String)
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO (Maybe String)) -> IO (Maybe String))
-> (Ptr MYSQL -> IO (Maybe String)) -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr ->
(CString -> IO String) -> CString -> IO (Maybe String)
forall a b. (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
withPtr CString -> IO String
peekCString (CString -> IO (Maybe String)) -> IO CString -> IO (Maybe String)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr MYSQL -> IO CString
mysql_get_ssl_cipher Ptr MYSQL
ptr
serverStatus :: Connection -> IO String
serverStatus :: Connection -> IO String
serverStatus Connection
conn = Connection -> (Ptr MYSQL -> IO String) -> IO String
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO String) -> IO String)
-> (Ptr MYSQL -> IO String) -> IO String
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr -> do
CString
st <- Ptr MYSQL -> IO CString
mysql_stat Ptr MYSQL
ptr
String -> Connection -> CString -> IO ()
forall a. String -> Connection -> Ptr a -> IO ()
checkNull String
"serverStatus" Connection
conn CString
st
CString -> IO String
peekCString CString
st
clientInfo :: String
clientInfo :: String
clientInfo = IO String -> String
forall a. IO a -> a
unsafePerformIO (IO String -> String) -> IO String -> String
forall a b. (a -> b) -> a -> b
$ CString -> IO String
peekCString CString
mysql_get_client_info
{-# NOINLINE clientInfo #-}
clientVersion :: Word
clientVersion :: Word
clientVersion = CULong -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral CULong
mysql_get_client_version
{-# NOINLINE clientVersion #-}
autocommit :: Connection -> Bool -> IO ()
autocommit :: Connection -> Bool -> IO ()
autocommit Connection
conn Bool
onOff = Connection -> (Ptr MYSQL -> IO ()) -> IO ()
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO ()) -> IO ()) -> (Ptr MYSQL -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr ->
Ptr MYSQL -> MyBool -> IO MyBool
mysql_autocommit Ptr MYSQL
ptr MyBool
b IO MyBool -> (MyBool -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Connection -> MyBool -> IO ()
forall a. (Eq a, Num a) => String -> Connection -> a -> IO ()
check String
"autocommit" Connection
conn
where b :: MyBool
b = if Bool
onOff then MyBool
1 else MyBool
0
changeUser :: Connection -> String -> String -> Maybe String -> IO ()
changeUser :: Connection -> String -> String -> Maybe String -> IO ()
changeUser Connection
conn String
user String
pass Maybe String
mdb =
String -> (CString -> IO ()) -> IO ()
forall a. String -> (CString -> IO a) -> IO a
withCString String
user ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \CString
cuser ->
String -> (CString -> IO ()) -> IO ()
forall a. String -> (CString -> IO a) -> IO a
withCString String
pass ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \CString
cpass ->
Maybe String -> (CString -> IO ()) -> IO ()
forall a. Maybe String -> (CString -> IO a) -> IO a
withMaybeString Maybe String
mdb ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \CString
cdb ->
Connection -> (Ptr MYSQL -> IO ()) -> IO ()
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO ()) -> IO ()) -> (Ptr MYSQL -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr ->
Ptr MYSQL -> CString -> CString -> CString -> IO MyBool
mysql_change_user Ptr MYSQL
ptr CString
cuser CString
cpass CString
cdb IO MyBool -> (MyBool -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Connection -> MyBool -> IO ()
forall a. (Eq a, Num a) => String -> Connection -> a -> IO ()
check String
"changeUser" Connection
conn
selectDB :: Connection -> String -> IO ()
selectDB :: Connection -> String -> IO ()
selectDB Connection
conn String
db =
String -> (CString -> IO ()) -> IO ()
forall a. String -> (CString -> IO a) -> IO a
withCString String
db ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \CString
cdb ->
Connection -> (Ptr MYSQL -> IO ()) -> IO ()
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO ()) -> IO ()) -> (Ptr MYSQL -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr ->
Ptr MYSQL -> CString -> IO CInt
mysql_select_db Ptr MYSQL
ptr CString
cdb IO CInt -> (CInt -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Connection -> CInt -> IO ()
forall a. (Eq a, Num a) => String -> Connection -> a -> IO ()
check String
"selectDB" Connection
conn
query :: Connection -> ByteString -> IO ()
query :: Connection -> ByteString -> IO ()
query Connection
conn ByteString
q = Connection -> (Ptr MYSQL -> IO ()) -> IO ()
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO ()) -> IO ()) -> (Ptr MYSQL -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr ->
ByteString -> (CStringLen -> IO ()) -> IO ()
forall a. ByteString -> (CStringLen -> IO a) -> IO a
unsafeUseAsCStringLen ByteString
q ((CStringLen -> IO ()) -> IO ()) -> (CStringLen -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(CString
p,Int
l) ->
Ptr MYSQL -> CString -> CULong -> IO CInt
mysql_real_query Ptr MYSQL
ptr CString
p (Int -> CULong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
l) IO CInt -> (CInt -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Connection -> CInt -> IO ()
forall a. (Eq a, Num a) => String -> Connection -> a -> IO ()
check String
"query" Connection
conn
insertID :: Connection -> IO Word64
insertID :: Connection -> IO Word64
insertID Connection
conn = CULLong -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CULLong -> Word64) -> IO CULLong -> IO Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Connection -> (Ptr MYSQL -> IO CULLong) -> IO CULLong
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO CULLong) -> IO CULLong)
-> (Ptr MYSQL -> IO CULLong) -> IO CULLong
forall a b. (a -> b) -> a -> b
$ Ptr MYSQL -> IO CULLong
mysql_insert_id)
fieldCount :: Either Connection Result -> IO Int
fieldCount :: Either Connection Result -> IO Int
fieldCount (Right Result
EmptyResult) = Int -> IO Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
0
fieldCount (Right Result
res) = Int -> IO Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Result -> Int
resFields Result
res)
fieldCount (Left Connection
conn) =
Connection -> (Ptr MYSQL -> IO Int) -> IO Int
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO Int) -> IO Int)
-> (Ptr MYSQL -> IO Int) -> IO Int
forall a b. (a -> b) -> a -> b
$ (CUInt -> Int) -> IO CUInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CUInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (IO CUInt -> IO Int)
-> (Ptr MYSQL -> IO CUInt) -> Ptr MYSQL -> IO Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr MYSQL -> IO CUInt
mysql_field_count
affectedRows :: Connection -> IO Int64
affectedRows :: Connection -> IO Int64
affectedRows Connection
conn = Connection -> (Ptr MYSQL -> IO Int64) -> IO Int64
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO Int64) -> IO Int64)
-> (Ptr MYSQL -> IO Int64) -> IO Int64
forall a b. (a -> b) -> a -> b
$ (CULLong -> Int64) -> IO CULLong -> IO Int64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CULLong -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (IO CULLong -> IO Int64)
-> (Ptr MYSQL -> IO CULLong) -> Ptr MYSQL -> IO Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr MYSQL -> IO CULLong
mysql_affected_rows
storeResult :: Connection -> IO Result
storeResult :: Connection -> IO Result
storeResult = String
-> (Ptr MYSQL -> IO (Ptr MYSQL_RES))
-> (Ptr MYSQL_RES -> IO (Ptr Field))
-> (Ptr MYSQL_RES -> IO MYSQL_ROW)
-> (Ptr MYSQL_RES -> IO (Ptr CULong))
-> (Ptr MYSQL_RES -> IO ())
-> Connection
-> IO Result
frobResult String
"storeResult" Ptr MYSQL -> IO (Ptr MYSQL_RES)
mysql_store_result
Ptr MYSQL_RES -> IO (Ptr Field)
mysql_fetch_fields_nonblock
Ptr MYSQL_RES -> IO MYSQL_ROW
mysql_fetch_row_nonblock
Ptr MYSQL_RES -> IO (Ptr CULong)
mysql_fetch_lengths_nonblock
Ptr MYSQL_RES -> IO ()
mysql_free_result_nonblock
useResult :: Connection -> IO Result
useResult :: Connection -> IO Result
useResult = String
-> (Ptr MYSQL -> IO (Ptr MYSQL_RES))
-> (Ptr MYSQL_RES -> IO (Ptr Field))
-> (Ptr MYSQL_RES -> IO MYSQL_ROW)
-> (Ptr MYSQL_RES -> IO (Ptr CULong))
-> (Ptr MYSQL_RES -> IO ())
-> Connection
-> IO Result
frobResult String
"useResult" Ptr MYSQL -> IO (Ptr MYSQL_RES)
mysql_use_result
Ptr MYSQL_RES -> IO (Ptr Field)
mysql_fetch_fields
Ptr MYSQL_RES -> IO MYSQL_ROW
mysql_fetch_row
Ptr MYSQL_RES -> IO (Ptr CULong)
mysql_fetch_lengths
Ptr MYSQL_RES -> IO ()
mysql_free_result
frobResult :: String
-> (Ptr MYSQL -> IO (Ptr MYSQL_RES))
-> (Ptr MYSQL_RES -> IO (Ptr Field))
-> (Ptr MYSQL_RES -> IO MYSQL_ROW)
-> (Ptr MYSQL_RES -> IO (Ptr CULong))
-> (Ptr MYSQL_RES -> IO ())
-> Connection -> IO Result
frobResult :: String
-> (Ptr MYSQL -> IO (Ptr MYSQL_RES))
-> (Ptr MYSQL_RES -> IO (Ptr Field))
-> (Ptr MYSQL_RES -> IO MYSQL_ROW)
-> (Ptr MYSQL_RES -> IO (Ptr CULong))
-> (Ptr MYSQL_RES -> IO ())
-> Connection
-> IO Result
frobResult String
func Ptr MYSQL -> IO (Ptr MYSQL_RES)
frob Ptr MYSQL_RES -> IO (Ptr Field)
fetchFieldsFunc Ptr MYSQL_RES -> IO MYSQL_ROW
fetchRowFunc Ptr MYSQL_RES -> IO (Ptr CULong)
fetchLengthsFunc
Ptr MYSQL_RES -> IO ()
myFreeResult Connection
conn =
Connection -> (Ptr MYSQL -> IO Result) -> IO Result
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO Result) -> IO Result)
-> (Ptr MYSQL -> IO Result) -> IO Result
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr -> do
IORef (Maybe (Weak Result)) -> IO ()
cleanupConnResult (Connection -> IORef (Maybe (Weak Result))
connResult Connection
conn)
Ptr MYSQL_RES
res <- Ptr MYSQL -> IO (Ptr MYSQL_RES)
frob Ptr MYSQL
ptr
CUInt
fields <- Ptr MYSQL -> IO CUInt
mysql_field_count Ptr MYSQL
ptr
IORef Bool
valid <- Bool -> IO (IORef Bool)
forall a. a -> IO (IORef a)
newIORef Bool
True
if Ptr MYSQL_RES
res Ptr MYSQL_RES -> Ptr MYSQL_RES -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr MYSQL_RES
forall a. Ptr a
nullPtr
then if CUInt
fields CUInt -> CUInt -> Bool
forall a. Eq a => a -> a -> Bool
== CUInt
0
then Result -> IO Result
forall (m :: * -> *) a. Monad m => a -> m a
return Result
EmptyResult
else String -> Connection -> IO Result
forall a. String -> Connection -> IO a
connectionError String
func Connection
conn
else do
ForeignPtr MYSQL_RES
fp <- Ptr MYSQL_RES -> IO () -> IO (ForeignPtr MYSQL_RES)
forall a. Ptr a -> IO () -> IO (ForeignPtr a)
newForeignPtr Ptr MYSQL_RES
res (IO () -> IO (ForeignPtr MYSQL_RES))
-> IO () -> IO (ForeignPtr MYSQL_RES)
forall a b. (a -> b) -> a -> b
$ IORef Bool -> (Ptr MYSQL_RES -> IO ()) -> Ptr MYSQL_RES -> IO ()
freeResult_ IORef Bool
valid Ptr MYSQL_RES -> IO ()
myFreeResult Ptr MYSQL_RES
res
let ret :: Result
ret = Result :: ForeignPtr MYSQL_RES
-> Int
-> Connection
-> IORef Bool
-> (Ptr MYSQL_RES -> IO (Ptr Field))
-> (Ptr MYSQL_RES -> IO MYSQL_ROW)
-> (Ptr MYSQL_RES -> IO (Ptr CULong))
-> (Ptr MYSQL_RES -> IO ())
-> Result
Result {
resFP :: ForeignPtr MYSQL_RES
resFP = ForeignPtr MYSQL_RES
fp
, resFields :: Int
resFields = CUInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CUInt
fields
, resConnection :: Connection
resConnection = Connection
conn
, resValid :: IORef Bool
resValid = IORef Bool
valid
, resFetchFields :: Ptr MYSQL_RES -> IO (Ptr Field)
resFetchFields = Ptr MYSQL_RES -> IO (Ptr Field)
fetchFieldsFunc
, resFetchRow :: Ptr MYSQL_RES -> IO MYSQL_ROW
resFetchRow = Ptr MYSQL_RES -> IO MYSQL_ROW
fetchRowFunc
, resFetchLengths :: Ptr MYSQL_RES -> IO (Ptr CULong)
resFetchLengths = Ptr MYSQL_RES -> IO (Ptr CULong)
fetchLengthsFunc
, resFreeResult :: Ptr MYSQL_RES -> IO ()
resFreeResult = Ptr MYSQL_RES -> IO ()
myFreeResult
}
Weak Result
weak <- Result -> Maybe (IO ()) -> IO (Weak Result)
forall k. k -> Maybe (IO ()) -> IO (Weak k)
mkWeakPtr Result
ret (IO () -> Maybe (IO ())
forall a. a -> Maybe a
Just (IORef Bool -> (Ptr MYSQL_RES -> IO ()) -> Ptr MYSQL_RES -> IO ()
freeResult_ IORef Bool
valid Ptr MYSQL_RES -> IO ()
myFreeResult Ptr MYSQL_RES
res))
IORef (Maybe (Weak Result)) -> Maybe (Weak Result) -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Connection -> IORef (Maybe (Weak Result))
connResult Connection
conn) (Weak Result -> Maybe (Weak Result)
forall a. a -> Maybe a
Just Weak Result
weak)
Result -> IO Result
forall (m :: * -> *) a. Monad m => a -> m a
return Result
ret
freeResult :: Result -> IO ()
freeResult :: Result -> IO ()
freeResult Result{Int
ForeignPtr MYSQL_RES
IORef Bool
Connection
Ptr MYSQL_RES -> IO MYSQL_ROW
Ptr MYSQL_RES -> IO (Ptr CULong)
Ptr MYSQL_RES -> IO (Ptr Field)
Ptr MYSQL_RES -> IO ()
resFreeResult :: Ptr MYSQL_RES -> IO ()
resFetchLengths :: Ptr MYSQL_RES -> IO (Ptr CULong)
resFetchRow :: Ptr MYSQL_RES -> IO MYSQL_ROW
resFetchFields :: Ptr MYSQL_RES -> IO (Ptr Field)
resValid :: IORef Bool
resConnection :: Connection
resFields :: Int
resFP :: ForeignPtr MYSQL_RES
resFreeResult :: Result -> Ptr MYSQL_RES -> IO ()
resFetchLengths :: Result -> Ptr MYSQL_RES -> IO (Ptr CULong)
resFetchRow :: Result -> Ptr MYSQL_RES -> IO MYSQL_ROW
resFetchFields :: Result -> Ptr MYSQL_RES -> IO (Ptr Field)
resValid :: Result -> IORef Bool
resConnection :: Result -> Connection
resFields :: Result -> Int
resFP :: Result -> ForeignPtr MYSQL_RES
..} = ForeignPtr MYSQL_RES -> (Ptr MYSQL_RES -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr MYSQL_RES
resFP ((Ptr MYSQL_RES -> IO ()) -> IO ())
-> (Ptr MYSQL_RES -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$
IORef Bool -> (Ptr MYSQL_RES -> IO ()) -> Ptr MYSQL_RES -> IO ()
freeResult_ IORef Bool
resValid Ptr MYSQL_RES -> IO ()
resFreeResult
freeResult Result
EmptyResult = () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
isResultValid :: Result -> IO Bool
isResultValid :: Result -> IO Bool
isResultValid Result{Int
ForeignPtr MYSQL_RES
IORef Bool
Connection
Ptr MYSQL_RES -> IO MYSQL_ROW
Ptr MYSQL_RES -> IO (Ptr CULong)
Ptr MYSQL_RES -> IO (Ptr Field)
Ptr MYSQL_RES -> IO ()
resFreeResult :: Ptr MYSQL_RES -> IO ()
resFetchLengths :: Ptr MYSQL_RES -> IO (Ptr CULong)
resFetchRow :: Ptr MYSQL_RES -> IO MYSQL_ROW
resFetchFields :: Ptr MYSQL_RES -> IO (Ptr Field)
resValid :: IORef Bool
resConnection :: Connection
resFields :: Int
resFP :: ForeignPtr MYSQL_RES
resFreeResult :: Result -> Ptr MYSQL_RES -> IO ()
resFetchLengths :: Result -> Ptr MYSQL_RES -> IO (Ptr CULong)
resFetchRow :: Result -> Ptr MYSQL_RES -> IO MYSQL_ROW
resFetchFields :: Result -> Ptr MYSQL_RES -> IO (Ptr Field)
resValid :: Result -> IORef Bool
resConnection :: Result -> Connection
resFields :: Result -> Int
resFP :: Result -> ForeignPtr MYSQL_RES
..} = IORef Bool -> IO Bool
forall a. IORef a -> IO a
readIORef IORef Bool
resValid
isResultValid Result
EmptyResult = Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
freeResult_ :: IORef Bool -> (Ptr MYSQL_RES -> IO ()) -> Ptr MYSQL_RES -> IO ()
freeResult_ :: IORef Bool -> (Ptr MYSQL_RES -> IO ()) -> Ptr MYSQL_RES -> IO ()
freeResult_ IORef Bool
valid Ptr MYSQL_RES -> IO ()
free Ptr MYSQL_RES
ptr = do
Bool
wasValid <- IORef Bool -> (Bool -> (Bool, Bool)) -> IO Bool
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef IORef Bool
valid ((Bool -> (Bool, Bool)) -> IO Bool)
-> (Bool -> (Bool, Bool)) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \Bool
prev -> (Bool
False, Bool
prev)
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
wasValid (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr MYSQL_RES -> IO ()
free Ptr MYSQL_RES
ptr
fetchRow :: Result -> IO [Maybe ByteString]
fetchRow :: Result -> IO [Maybe ByteString]
fetchRow res :: Result
res@Result{Int
ForeignPtr MYSQL_RES
IORef Bool
Connection
Ptr MYSQL_RES -> IO MYSQL_ROW
Ptr MYSQL_RES -> IO (Ptr CULong)
Ptr MYSQL_RES -> IO (Ptr Field)
Ptr MYSQL_RES -> IO ()
resFreeResult :: Ptr MYSQL_RES -> IO ()
resFetchLengths :: Ptr MYSQL_RES -> IO (Ptr CULong)
resFetchRow :: Ptr MYSQL_RES -> IO MYSQL_ROW
resFetchFields :: Ptr MYSQL_RES -> IO (Ptr Field)
resValid :: IORef Bool
resConnection :: Connection
resFields :: Int
resFP :: ForeignPtr MYSQL_RES
resFreeResult :: Result -> Ptr MYSQL_RES -> IO ()
resFetchLengths :: Result -> Ptr MYSQL_RES -> IO (Ptr CULong)
resFetchRow :: Result -> Ptr MYSQL_RES -> IO MYSQL_ROW
resFetchFields :: Result -> Ptr MYSQL_RES -> IO (Ptr Field)
resValid :: Result -> IORef Bool
resConnection :: Result -> Connection
resFields :: Result -> Int
resFP :: Result -> ForeignPtr MYSQL_RES
..} = String
-> Result
-> (Ptr MYSQL_RES -> IO [Maybe ByteString])
-> IO [Maybe ByteString]
forall a. String -> Result -> (Ptr MYSQL_RES -> IO a) -> IO a
withRes String
"fetchRow" Result
res ((Ptr MYSQL_RES -> IO [Maybe ByteString]) -> IO [Maybe ByteString])
-> (Ptr MYSQL_RES -> IO [Maybe ByteString])
-> IO [Maybe ByteString]
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL_RES
ptr -> do
MYSQL_ROW
rowPtr <- Ptr MYSQL_RES -> IO MYSQL_ROW
resFetchRow Ptr MYSQL_RES
ptr
if MYSQL_ROW
rowPtr MYSQL_ROW -> MYSQL_ROW -> Bool
forall a. Eq a => a -> a -> Bool
== MYSQL_ROW
forall a. Ptr a
nullPtr
then [Maybe ByteString] -> IO [Maybe ByteString]
forall (m :: * -> *) a. Monad m => a -> m a
return []
else do
Ptr CULong
lenPtr <- Ptr MYSQL_RES -> IO (Ptr CULong)
resFetchLengths Ptr MYSQL_RES
ptr
String -> Connection -> Ptr CULong -> IO ()
forall a. String -> Connection -> Ptr a -> IO ()
checkNull String
"fetchRow" Connection
resConnection Ptr CULong
lenPtr
let go :: a -> Ptr a -> IO (Maybe ByteString)
go a
len = (Ptr a -> IO ByteString) -> Ptr a -> IO (Maybe ByteString)
forall a b. (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
withPtr ((Ptr a -> IO ByteString) -> Ptr a -> IO (Maybe ByteString))
-> (Ptr a -> IO ByteString) -> Ptr a -> IO (Maybe ByteString)
forall a b. (a -> b) -> a -> b
$ \Ptr a
colPtr ->
Int -> (Ptr Word8 -> IO ()) -> IO ByteString
create (a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
len) ((Ptr Word8 -> IO ()) -> IO ByteString)
-> (Ptr Word8 -> IO ()) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
d ->
Ptr Word8 -> Ptr Word8 -> Int -> IO ()
memcpy Ptr Word8
d (Ptr a -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr Ptr a
colPtr) (a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
len)
[IO (Maybe ByteString)] -> IO [Maybe ByteString]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence ([IO (Maybe ByteString)] -> IO [Maybe ByteString])
-> IO [IO (Maybe ByteString)] -> IO [Maybe ByteString]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (CULong -> CString -> IO (Maybe ByteString))
-> [CULong] -> [CString] -> [IO (Maybe ByteString)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith CULong -> CString -> IO (Maybe ByteString)
forall a a. Integral a => a -> Ptr a -> IO (Maybe ByteString)
go ([CULong] -> [CString] -> [IO (Maybe ByteString)])
-> IO [CULong] -> IO ([CString] -> [IO (Maybe ByteString)])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Ptr CULong -> IO [CULong]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
resFields Ptr CULong
lenPtr
IO ([CString] -> [IO (Maybe ByteString)])
-> IO [CString] -> IO [IO (Maybe ByteString)]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> MYSQL_ROW -> IO [CString]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
resFields MYSQL_ROW
rowPtr
fetchRow Result
EmptyResult = [Maybe ByteString] -> IO [Maybe ByteString]
forall (m :: * -> *) a. Monad m => a -> m a
return []
fetchFields :: Result -> IO [Field]
fetchFields :: Result -> IO [Field]
fetchFields res :: Result
res@Result{Int
ForeignPtr MYSQL_RES
IORef Bool
Connection
Ptr MYSQL_RES -> IO MYSQL_ROW
Ptr MYSQL_RES -> IO (Ptr CULong)
Ptr MYSQL_RES -> IO (Ptr Field)
Ptr MYSQL_RES -> IO ()
resFreeResult :: Ptr MYSQL_RES -> IO ()
resFetchLengths :: Ptr MYSQL_RES -> IO (Ptr CULong)
resFetchRow :: Ptr MYSQL_RES -> IO MYSQL_ROW
resFetchFields :: Ptr MYSQL_RES -> IO (Ptr Field)
resValid :: IORef Bool
resConnection :: Connection
resFields :: Int
resFP :: ForeignPtr MYSQL_RES
resFreeResult :: Result -> Ptr MYSQL_RES -> IO ()
resFetchLengths :: Result -> Ptr MYSQL_RES -> IO (Ptr CULong)
resFetchRow :: Result -> Ptr MYSQL_RES -> IO MYSQL_ROW
resFetchFields :: Result -> Ptr MYSQL_RES -> IO (Ptr Field)
resValid :: Result -> IORef Bool
resConnection :: Result -> Connection
resFields :: Result -> Int
resFP :: Result -> ForeignPtr MYSQL_RES
..} = String -> Result -> (Ptr MYSQL_RES -> IO [Field]) -> IO [Field]
forall a. String -> Result -> (Ptr MYSQL_RES -> IO a) -> IO a
withRes String
"fetchFields" Result
res ((Ptr MYSQL_RES -> IO [Field]) -> IO [Field])
-> (Ptr MYSQL_RES -> IO [Field]) -> IO [Field]
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL_RES
ptr -> do
Int -> Ptr Field -> IO [Field]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
resFields (Ptr Field -> IO [Field]) -> IO (Ptr Field) -> IO [Field]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr MYSQL_RES -> IO (Ptr Field)
resFetchFields Ptr MYSQL_RES
ptr
fetchFields Result
EmptyResult = [Field] -> IO [Field]
forall (m :: * -> *) a. Monad m => a -> m a
return []
dataSeek :: Result -> Int64 -> IO ()
dataSeek :: Result -> Int64 -> IO ()
dataSeek Result
res Int64
row = String -> Result -> (Ptr MYSQL_RES -> IO ()) -> IO ()
forall a. String -> Result -> (Ptr MYSQL_RES -> IO a) -> IO a
withRes String
"dataSeek" Result
res ((Ptr MYSQL_RES -> IO ()) -> IO ())
-> (Ptr MYSQL_RES -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL_RES
ptr ->
Ptr MYSQL_RES -> CULLong -> IO ()
mysql_data_seek Ptr MYSQL_RES
ptr (Int64 -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
row)
rowTell :: Result -> IO Row
rowTell :: Result -> IO Row
rowTell Result
res = String -> Result -> (Ptr MYSQL_RES -> IO Row) -> IO Row
forall a. String -> Result -> (Ptr MYSQL_RES -> IO a) -> IO a
withRes String
"rowTell" Result
res ((Ptr MYSQL_RES -> IO Row) -> IO Row)
-> (Ptr MYSQL_RES -> IO Row) -> IO Row
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL_RES
ptr ->
MYSQL_ROW_OFFSET -> Row
Row (MYSQL_ROW_OFFSET -> Row) -> IO MYSQL_ROW_OFFSET -> IO Row
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr MYSQL_RES -> IO MYSQL_ROW_OFFSET
mysql_row_tell Ptr MYSQL_RES
ptr
rowSeek :: Result -> Row -> IO Row
rowSeek :: Result -> Row -> IO Row
rowSeek Result
res (Row MYSQL_ROW_OFFSET
row) = String -> Result -> (Ptr MYSQL_RES -> IO Row) -> IO Row
forall a. String -> Result -> (Ptr MYSQL_RES -> IO a) -> IO a
withRes String
"rowSeek" Result
res ((Ptr MYSQL_RES -> IO Row) -> IO Row)
-> (Ptr MYSQL_RES -> IO Row) -> IO Row
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL_RES
ptr ->
MYSQL_ROW_OFFSET -> Row
Row (MYSQL_ROW_OFFSET -> Row) -> IO MYSQL_ROW_OFFSET -> IO Row
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr MYSQL_RES -> MYSQL_ROW_OFFSET -> IO MYSQL_ROW_OFFSET
mysql_row_seek Ptr MYSQL_RES
ptr MYSQL_ROW_OFFSET
row
nextResult :: Connection -> IO Bool
nextResult :: Connection -> IO Bool
nextResult Connection
conn = Connection -> (Ptr MYSQL -> IO Bool) -> IO Bool
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO Bool) -> IO Bool)
-> (Ptr MYSQL -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr -> do
IORef (Maybe (Weak Result)) -> IO ()
cleanupConnResult (Connection -> IORef (Maybe (Weak Result))
connResult Connection
conn)
CInt
i <- Ptr MYSQL -> IO CInt
mysql_next_result Ptr MYSQL
ptr
case CInt
i of
CInt
0 -> Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
-1 -> Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
CInt
_ -> String -> Connection -> IO Bool
forall a. String -> Connection -> IO a
connectionError String
"nextResult" Connection
conn
commit :: Connection -> IO ()
commit :: Connection -> IO ()
commit Connection
conn = Connection -> (Ptr MYSQL -> IO ()) -> IO ()
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO ()) -> IO ()) -> (Ptr MYSQL -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr ->
Ptr MYSQL -> IO MyBool
mysql_commit Ptr MYSQL
ptr IO MyBool -> (MyBool -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Connection -> MyBool -> IO ()
forall a. (Eq a, Num a) => String -> Connection -> a -> IO ()
check String
"commit" Connection
conn
rollback :: Connection -> IO ()
rollback :: Connection -> IO ()
rollback Connection
conn = Connection -> (Ptr MYSQL -> IO ()) -> IO ()
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO ()) -> IO ()) -> (Ptr MYSQL -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr ->
Ptr MYSQL -> IO MyBool
mysql_rollback Ptr MYSQL
ptr IO MyBool -> (MyBool -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Connection -> MyBool -> IO ()
forall a. (Eq a, Num a) => String -> Connection -> a -> IO ()
check String
"rollback" Connection
conn
escape :: Connection -> ByteString -> IO ByteString
escape :: Connection -> ByteString -> IO ByteString
escape Connection
conn ByteString
bs = Connection -> (Ptr MYSQL -> IO ByteString) -> IO ByteString
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO ByteString) -> IO ByteString)
-> (Ptr MYSQL -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr MYSQL
ptr ->
ByteString -> (CStringLen -> IO ByteString) -> IO ByteString
forall a. ByteString -> (CStringLen -> IO a) -> IO a
unsafeUseAsCStringLen ByteString
bs ((CStringLen -> IO ByteString) -> IO ByteString)
-> (CStringLen -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \(CString
p,Int
l) ->
Int -> (Ptr Word8 -> IO Int) -> IO ByteString
createAndTrim (Int
lInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) ((Ptr Word8 -> IO Int) -> IO ByteString)
-> (Ptr Word8 -> IO Int) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
to ->
CULong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CULong -> Int) -> IO CULong -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr MYSQL -> CString -> CString -> CULong -> IO CULong
mysql_real_escape_string Ptr MYSQL
ptr (Ptr Word8 -> CString
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
to) CString
p
(Int -> CULong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
l)
withConn :: Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn :: Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn = ForeignPtr MYSQL -> (Ptr MYSQL -> IO a) -> IO a
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (Connection -> ForeignPtr MYSQL
connFP Connection
conn)
initLibrary :: IO ()
initLibrary :: IO ()
initLibrary = do
CInt
r <- CInt -> Ptr (Ptr Char) -> Ptr (Ptr Char) -> IO CInt
mysql_library_init CInt
0 Ptr (Ptr Char)
forall a. Ptr a
nullPtr Ptr (Ptr Char)
forall a. Ptr a
nullPtr
if CInt
r CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
== CInt
0
then () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
else MySQLError -> IO ()
forall a e. Exception e => e -> a
throw (MySQLError -> IO ()) -> MySQLError -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> Int -> String -> MySQLError
ConnectionError String
"initLibrary" (-Int
1)
String
"mysql_library_init failed"
initThread :: IO ()
initThread :: IO ()
initThread = do
MyBool
r <- IO MyBool
mysql_thread_init
if MyBool
r MyBool -> MyBool -> Bool
forall a. Eq a => a -> a -> Bool
== MyBool
0
then () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
else MySQLError -> IO ()
forall a e. Exception e => e -> a
throw (MySQLError -> IO ()) -> MySQLError -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> Int -> String -> MySQLError
ConnectionError String
"initThread" (-Int
1)
String
"mysql_thread_init failed"
endThread :: IO ()
endThread :: IO ()
endThread = IO ()
mysql_thread_end
withRes :: String -> Result -> (Ptr MYSQL_RES -> IO a) -> IO a
withRes :: String -> Result -> (Ptr MYSQL_RES -> IO a) -> IO a
withRes String
func Result
res Ptr MYSQL_RES -> IO a
act = do
Bool
valid <- IORef Bool -> IO Bool
forall a. IORef a -> IO a
readIORef (Result -> IORef Bool
resValid Result
res)
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
valid (IO () -> IO ()) -> (MySQLError -> IO ()) -> MySQLError -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MySQLError -> IO ()
forall a e. Exception e => e -> a
throw (MySQLError -> IO ()) -> MySQLError -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> Int -> String -> MySQLError
ResultError String
func Int
0 String
"result is no longer usable"
ForeignPtr MYSQL_RES -> (Ptr MYSQL_RES -> IO a) -> IO a
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (Result -> ForeignPtr MYSQL_RES
resFP Result
res) Ptr MYSQL_RES -> IO a
act
withString :: String -> (CString -> IO a) -> IO a
withString :: String -> (CString -> IO a) -> IO a
withString [] CString -> IO a
act = CString -> IO a
act CString
forall a. Ptr a
nullPtr
withString String
xs CString -> IO a
act = String -> (CString -> IO a) -> IO a
forall a. String -> (CString -> IO a) -> IO a
withCString String
xs CString -> IO a
act
withMaybeString :: Maybe String -> (CString -> IO a) -> IO a
withMaybeString :: Maybe String -> (CString -> IO a) -> IO a
withMaybeString Maybe String
Nothing CString -> IO a
act = CString -> IO a
act CString
forall a. Ptr a
nullPtr
withMaybeString (Just String
xs) CString -> IO a
act = String -> (CString -> IO a) -> IO a
forall a. String -> (CString -> IO a) -> IO a
withCString String
xs CString -> IO a
act
check :: (Eq a, Num a) => String -> Connection -> a -> IO ()
check :: String -> Connection -> a -> IO ()
check String
func Connection
conn a
r = Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (a
r a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> Connection -> IO ()
forall a. String -> Connection -> IO a
connectionError String
func Connection
conn
{-# INLINE check #-}
checkNull :: String -> Connection -> Ptr a -> IO ()
checkNull :: String -> Connection -> Ptr a -> IO ()
checkNull String
func Connection
conn Ptr a
p = Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Ptr a
p Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
forall a. Ptr a
nullPtr) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> Connection -> IO ()
forall a. String -> Connection -> IO a
connectionError String
func Connection
conn
{-# INLINE checkNull #-}
withPtr :: (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
withPtr :: (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
withPtr Ptr a -> IO b
act Ptr a
p | Ptr a
p Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
forall a. Ptr a
nullPtr = Maybe b -> IO (Maybe b)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe b
forall a. Maybe a
Nothing
| Bool
otherwise = b -> Maybe b
forall a. a -> Maybe a
Just (b -> Maybe b) -> IO b -> IO (Maybe b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr a -> IO b
act Ptr a
p
connectionError :: String -> Connection -> IO a
connectionError :: String -> Connection -> IO a
connectionError String
func Connection
conn = Connection -> (Ptr MYSQL -> IO a) -> IO a
forall a. Connection -> (Ptr MYSQL -> IO a) -> IO a
withConn Connection
conn ((Ptr MYSQL -> IO a) -> IO a) -> (Ptr MYSQL -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ String -> Ptr MYSQL -> IO a
forall a. String -> Ptr MYSQL -> IO a
connectionError_ String
func
connectionError_ :: String -> Ptr MYSQL -> IO a
connectionError_ :: String -> Ptr MYSQL -> IO a
connectionError_ String
func Ptr MYSQL
ptr =do
CInt
errno <- Ptr MYSQL -> IO CInt
mysql_errno Ptr MYSQL
ptr
String
msg <- CString -> IO String
peekCString (CString -> IO String) -> IO CString -> IO String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr MYSQL -> IO CString
mysql_error Ptr MYSQL
ptr
MySQLError -> IO a
forall a e. Exception e => e -> a
throw (MySQLError -> IO a) -> MySQLError -> IO a
forall a b. (a -> b) -> a -> b
$ String -> Int -> String -> MySQLError
ConnectionError String
func (CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
errno) String
msg