module Database.MySQL.Base
(
MySQLConn
, ConnectInfo(..)
, defaultConnectInfo
, defaultConnectInfoMB4
, connect
, connectDetail
, close
, ping
, execute
, executeMany
, executeMany_
, execute_
, query_
, queryVector_
, query
, queryVector
, prepareStmt
, prepareStmtDetail
, executeStmt
, queryStmt
, queryStmtVector
, closeStmt
, resetStmt
, withTransaction
, QueryParam(..)
, Param (..)
, Query(..)
, renderParams
, command
, Stream.skipToEof
, NetworkException(..)
, UnconsumedResultSet(..)
, ERRException(..)
, UnexpectedPacket(..)
, DecodePacketException(..)
, WrongParamsCount(..)
, module Database.MySQL.Protocol.Auth
, module Database.MySQL.Protocol.Command
, module Database.MySQL.Protocol.ColumnDef
, module Database.MySQL.Protocol.Packet
, module Database.MySQL.Protocol.MySQLValue
) where
import Control.Exception (mask, onException, throwIO)
import Control.Monad
import qualified Data.ByteString.Lazy as L
import Data.IORef (writeIORef)
import Database.MySQL.Connection
import Database.MySQL.Protocol.Auth
import Database.MySQL.Protocol.ColumnDef
import Database.MySQL.Protocol.Command
import Database.MySQL.Protocol.MySQLValue
import Database.MySQL.Protocol.Packet
import Database.MySQL.Query
import System.IO.Streams (InputStream)
import qualified System.IO.Streams as Stream
import qualified Data.Vector as V
execute :: QueryParam p => MySQLConn -> Query -> [p] -> IO OK
execute :: forall p. QueryParam p => MySQLConn -> Query -> [p] -> IO OK
execute MySQLConn
conn Query
qry [p]
params = MySQLConn -> Query -> IO OK
execute_ MySQLConn
conn (Query -> [p] -> Query
forall p. QueryParam p => Query -> [p] -> Query
renderParams Query
qry [p]
params)
{-# SPECIALIZE execute :: MySQLConn -> Query -> [MySQLValue] -> IO OK #-}
{-# SPECIALIZE execute :: MySQLConn -> Query -> [Param] -> IO OK #-}
executeMany :: QueryParam p => MySQLConn -> Query -> [[p]] -> IO [OK]
executeMany :: forall p. QueryParam p => MySQLConn -> Query -> [[p]] -> IO [OK]
executeMany conn :: MySQLConn
conn@(MySQLConn InputStream Packet
is Packet -> IO ()
os IO ()
_ IORef Bool
_) Query
qry [[p]]
paramsList = do
MySQLConn -> IO ()
guardUnconsumed MySQLConn
conn
let qry' :: ByteString
qry' = ByteString -> [ByteString] -> ByteString
L.intercalate ByteString
";" ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ ([p] -> ByteString) -> [[p]] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map (Query -> ByteString
fromQuery (Query -> ByteString) -> ([p] -> Query) -> [p] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Query -> [p] -> Query
forall p. QueryParam p => Query -> [p] -> Query
renderParams Query
qry) [[p]]
paramsList
Command -> (Packet -> IO ()) -> IO ()
writeCommand (ByteString -> Command
COM_QUERY ByteString
qry') Packet -> IO ()
os
([p] -> IO OK) -> [[p]] -> IO [OK]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (\ [p]
_ -> InputStream Packet -> IO OK
waitCommandReply InputStream Packet
is) [[p]]
paramsList
{-# SPECIALIZE executeMany :: MySQLConn -> Query -> [[MySQLValue]] -> IO [OK] #-}
{-# SPECIALIZE executeMany :: MySQLConn -> Query -> [[Param]] -> IO [OK] #-}
executeMany_ :: MySQLConn -> Query -> IO [OK]
executeMany_ :: MySQLConn -> Query -> IO [OK]
executeMany_ conn :: MySQLConn
conn@(MySQLConn InputStream Packet
is Packet -> IO ()
os IO ()
_ IORef Bool
_) Query
qry = do
MySQLConn -> IO ()
guardUnconsumed MySQLConn
conn
Command -> (Packet -> IO ()) -> IO ()
writeCommand (ByteString -> Command
COM_QUERY (Query -> ByteString
fromQuery Query
qry)) Packet -> IO ()
os
InputStream Packet -> IO [OK]
waitCommandReplys InputStream Packet
is
execute_ :: MySQLConn -> Query -> IO OK
execute_ :: MySQLConn -> Query -> IO OK
execute_ MySQLConn
conn (Query ByteString
qry) = MySQLConn -> Command -> IO OK
command MySQLConn
conn (ByteString -> Command
COM_QUERY ByteString
qry)
query :: QueryParam p => MySQLConn -> Query -> [p] -> IO ([ColumnDef], InputStream [MySQLValue])
query :: forall p.
QueryParam p =>
MySQLConn
-> Query -> [p] -> IO ([ColumnDef], InputStream [MySQLValue])
query MySQLConn
conn Query
qry [p]
params = MySQLConn -> Query -> IO ([ColumnDef], InputStream [MySQLValue])
query_ MySQLConn
conn (Query -> [p] -> Query
forall p. QueryParam p => Query -> [p] -> Query
renderParams Query
qry [p]
params)
{-# SPECIALIZE query :: MySQLConn -> Query -> [MySQLValue] -> IO ([ColumnDef], InputStream [MySQLValue]) #-}
{-# SPECIALIZE query :: MySQLConn -> Query -> [Param] -> IO ([ColumnDef], InputStream [MySQLValue]) #-}
queryVector :: QueryParam p => MySQLConn -> Query -> [p] -> IO (V.Vector ColumnDef, InputStream (V.Vector MySQLValue))
queryVector :: forall p.
QueryParam p =>
MySQLConn
-> Query
-> [p]
-> IO (Vector ColumnDef, InputStream (Vector MySQLValue))
queryVector MySQLConn
conn Query
qry [p]
params = MySQLConn
-> Query -> IO (Vector ColumnDef, InputStream (Vector MySQLValue))
queryVector_ MySQLConn
conn (Query -> [p] -> Query
forall p. QueryParam p => Query -> [p] -> Query
renderParams Query
qry [p]
params)
{-# SPECIALIZE queryVector :: MySQLConn -> Query -> [MySQLValue] -> IO (V.Vector ColumnDef, InputStream (V.Vector MySQLValue)) #-}
{-# SPECIALIZE queryVector :: MySQLConn -> Query -> [Param] -> IO (V.Vector ColumnDef, InputStream (V.Vector MySQLValue)) #-}
query_ :: MySQLConn -> Query -> IO ([ColumnDef], InputStream [MySQLValue])
query_ :: MySQLConn -> Query -> IO ([ColumnDef], InputStream [MySQLValue])
query_ conn :: MySQLConn
conn@(MySQLConn InputStream Packet
is Packet -> IO ()
os IO ()
_ IORef Bool
consumed) (Query ByteString
qry) = do
MySQLConn -> IO ()
guardUnconsumed MySQLConn
conn
Command -> (Packet -> IO ()) -> IO ()
writeCommand (ByteString -> Command
COM_QUERY ByteString
qry) Packet -> IO ()
os
Packet
p <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
if Packet -> Bool
isERR Packet
p
then Packet -> IO ERR
forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
p IO ERR
-> (ERR -> IO ([ColumnDef], InputStream [MySQLValue]))
-> IO ([ColumnDef], InputStream [MySQLValue])
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ERRException -> IO ([ColumnDef], InputStream [MySQLValue])
forall e a. Exception e => e -> IO a
throwIO (ERRException -> IO ([ColumnDef], InputStream [MySQLValue]))
-> (ERR -> ERRException)
-> ERR
-> IO ([ColumnDef], InputStream [MySQLValue])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
else do
Int
len <- Get Int -> Packet -> IO Int
forall a. Get a -> Packet -> IO a
getFromPacket Get Int
getLenEncInt Packet
p
[ColumnDef]
fields <- Int -> IO ColumnDef -> IO [ColumnDef]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
len (IO ColumnDef -> IO [ColumnDef]) -> IO ColumnDef -> IO [ColumnDef]
forall a b. (a -> b) -> a -> b
$ (Packet -> IO ColumnDef
forall a. Binary a => Packet -> IO a
decodeFromPacket (Packet -> IO ColumnDef)
-> (InputStream Packet -> IO Packet)
-> InputStream Packet
-> IO ColumnDef
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< InputStream Packet -> IO Packet
readPacket) InputStream Packet
is
Packet
_ <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
IORef Bool -> Bool -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
False
InputStream [MySQLValue]
rows <- IO (Maybe [MySQLValue]) -> IO (InputStream [MySQLValue])
forall a. IO (Maybe a) -> IO (InputStream a)
Stream.makeInputStream (IO (Maybe [MySQLValue]) -> IO (InputStream [MySQLValue]))
-> IO (Maybe [MySQLValue]) -> IO (InputStream [MySQLValue])
forall a b. (a -> b) -> a -> b
$ do
Packet
q <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
if | Packet -> Bool
isEOF Packet
q -> IORef Bool -> Bool -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
True IO () -> IO (Maybe [MySQLValue]) -> IO (Maybe [MySQLValue])
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe [MySQLValue] -> IO (Maybe [MySQLValue])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe [MySQLValue]
forall a. Maybe a
Nothing
| Packet -> Bool
isERR Packet
q -> Packet -> IO ERR
forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
q IO ERR
-> (ERR -> IO (Maybe [MySQLValue])) -> IO (Maybe [MySQLValue])
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ERRException -> IO (Maybe [MySQLValue])
forall e a. Exception e => e -> IO a
throwIO (ERRException -> IO (Maybe [MySQLValue]))
-> (ERR -> ERRException) -> ERR -> IO (Maybe [MySQLValue])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
| Bool
otherwise -> [MySQLValue] -> Maybe [MySQLValue]
forall a. a -> Maybe a
Just ([MySQLValue] -> Maybe [MySQLValue])
-> IO [MySQLValue] -> IO (Maybe [MySQLValue])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get [MySQLValue] -> Packet -> IO [MySQLValue]
forall a. Get a -> Packet -> IO a
getFromPacket ([ColumnDef] -> Get [MySQLValue]
getTextRow [ColumnDef]
fields) Packet
q
([ColumnDef], InputStream [MySQLValue])
-> IO ([ColumnDef], InputStream [MySQLValue])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([ColumnDef]
fields, InputStream [MySQLValue]
rows)
queryVector_ :: MySQLConn -> Query -> IO (V.Vector ColumnDef, InputStream (V.Vector MySQLValue))
queryVector_ :: MySQLConn
-> Query -> IO (Vector ColumnDef, InputStream (Vector MySQLValue))
queryVector_ conn :: MySQLConn
conn@(MySQLConn InputStream Packet
is Packet -> IO ()
os IO ()
_ IORef Bool
consumed) (Query ByteString
qry) = do
MySQLConn -> IO ()
guardUnconsumed MySQLConn
conn
Command -> (Packet -> IO ()) -> IO ()
writeCommand (ByteString -> Command
COM_QUERY ByteString
qry) Packet -> IO ()
os
Packet
p <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
if Packet -> Bool
isERR Packet
p
then Packet -> IO ERR
forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
p IO ERR
-> (ERR -> IO (Vector ColumnDef, InputStream (Vector MySQLValue)))
-> IO (Vector ColumnDef, InputStream (Vector MySQLValue))
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ERRException
-> IO (Vector ColumnDef, InputStream (Vector MySQLValue))
forall e a. Exception e => e -> IO a
throwIO (ERRException
-> IO (Vector ColumnDef, InputStream (Vector MySQLValue)))
-> (ERR -> ERRException)
-> ERR
-> IO (Vector ColumnDef, InputStream (Vector MySQLValue))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
else do
Int
len <- Get Int -> Packet -> IO Int
forall a. Get a -> Packet -> IO a
getFromPacket Get Int
getLenEncInt Packet
p
Vector ColumnDef
fields <- Int -> IO ColumnDef -> IO (Vector ColumnDef)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
len (IO ColumnDef -> IO (Vector ColumnDef))
-> IO ColumnDef -> IO (Vector ColumnDef)
forall a b. (a -> b) -> a -> b
$ (Packet -> IO ColumnDef
forall a. Binary a => Packet -> IO a
decodeFromPacket (Packet -> IO ColumnDef)
-> (InputStream Packet -> IO Packet)
-> InputStream Packet
-> IO ColumnDef
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< InputStream Packet -> IO Packet
readPacket) InputStream Packet
is
Packet
_ <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
IORef Bool -> Bool -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
False
InputStream (Vector MySQLValue)
rows <- IO (Maybe (Vector MySQLValue))
-> IO (InputStream (Vector MySQLValue))
forall a. IO (Maybe a) -> IO (InputStream a)
Stream.makeInputStream (IO (Maybe (Vector MySQLValue))
-> IO (InputStream (Vector MySQLValue)))
-> IO (Maybe (Vector MySQLValue))
-> IO (InputStream (Vector MySQLValue))
forall a b. (a -> b) -> a -> b
$ do
Packet
q <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
if | Packet -> Bool
isEOF Packet
q -> IORef Bool -> Bool -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
True IO ()
-> IO (Maybe (Vector MySQLValue)) -> IO (Maybe (Vector MySQLValue))
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe (Vector MySQLValue) -> IO (Maybe (Vector MySQLValue))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Vector MySQLValue)
forall a. Maybe a
Nothing
| Packet -> Bool
isERR Packet
q -> Packet -> IO ERR
forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
q IO ERR
-> (ERR -> IO (Maybe (Vector MySQLValue)))
-> IO (Maybe (Vector MySQLValue))
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ERRException -> IO (Maybe (Vector MySQLValue))
forall e a. Exception e => e -> IO a
throwIO (ERRException -> IO (Maybe (Vector MySQLValue)))
-> (ERR -> ERRException) -> ERR -> IO (Maybe (Vector MySQLValue))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
| Bool
otherwise -> Vector MySQLValue -> Maybe (Vector MySQLValue)
forall a. a -> Maybe a
Just (Vector MySQLValue -> Maybe (Vector MySQLValue))
-> IO (Vector MySQLValue) -> IO (Maybe (Vector MySQLValue))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get (Vector MySQLValue) -> Packet -> IO (Vector MySQLValue)
forall a. Get a -> Packet -> IO a
getFromPacket (Vector ColumnDef -> Get (Vector MySQLValue)
getTextRowVector Vector ColumnDef
fields) Packet
q
(Vector ColumnDef, InputStream (Vector MySQLValue))
-> IO (Vector ColumnDef, InputStream (Vector MySQLValue))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Vector ColumnDef
fields, InputStream (Vector MySQLValue)
rows)
prepareStmt :: MySQLConn -> Query -> IO StmtID
prepareStmt :: MySQLConn -> Query -> IO StmtID
prepareStmt conn :: MySQLConn
conn@(MySQLConn InputStream Packet
is Packet -> IO ()
os IO ()
_ IORef Bool
_) (Query ByteString
stmt) = do
MySQLConn -> IO ()
guardUnconsumed MySQLConn
conn
Command -> (Packet -> IO ()) -> IO ()
writeCommand (ByteString -> Command
COM_STMT_PREPARE ByteString
stmt) Packet -> IO ()
os
Packet
p <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
if Packet -> Bool
isERR Packet
p
then Packet -> IO ERR
forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
p IO ERR -> (ERR -> IO StmtID) -> IO StmtID
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ERRException -> IO StmtID
forall e a. Exception e => e -> IO a
throwIO (ERRException -> IO StmtID)
-> (ERR -> ERRException) -> ERR -> IO StmtID
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
else do
StmtPrepareOK StmtID
stid Int
colCnt Int
paramCnt Int
_ <- Get StmtPrepareOK -> Packet -> IO StmtPrepareOK
forall a. Get a -> Packet -> IO a
getFromPacket Get StmtPrepareOK
getStmtPrepareOK Packet
p
()
_ <- Int -> IO Packet -> IO ()
forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
replicateM_ Int
paramCnt (InputStream Packet -> IO Packet
readPacket InputStream Packet
is)
()
_ <- Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
paramCnt Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (IO Packet -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (InputStream Packet -> IO Packet
readPacket InputStream Packet
is))
()
_ <- Int -> IO Packet -> IO ()
forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
replicateM_ Int
colCnt (InputStream Packet -> IO Packet
readPacket InputStream Packet
is)
()
_ <- Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
colCnt Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (IO Packet -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (InputStream Packet -> IO Packet
readPacket InputStream Packet
is))
StmtID -> IO StmtID
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return StmtID
stid
prepareStmtDetail :: MySQLConn -> Query -> IO (StmtPrepareOK, [ColumnDef], [ColumnDef])
prepareStmtDetail :: MySQLConn -> Query -> IO (StmtPrepareOK, [ColumnDef], [ColumnDef])
prepareStmtDetail conn :: MySQLConn
conn@(MySQLConn InputStream Packet
is Packet -> IO ()
os IO ()
_ IORef Bool
_) (Query ByteString
stmt) = do
MySQLConn -> IO ()
guardUnconsumed MySQLConn
conn
Command -> (Packet -> IO ()) -> IO ()
writeCommand (ByteString -> Command
COM_STMT_PREPARE ByteString
stmt) Packet -> IO ()
os
Packet
p <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
if Packet -> Bool
isERR Packet
p
then Packet -> IO ERR
forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
p IO ERR
-> (ERR -> IO (StmtPrepareOK, [ColumnDef], [ColumnDef]))
-> IO (StmtPrepareOK, [ColumnDef], [ColumnDef])
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ERRException -> IO (StmtPrepareOK, [ColumnDef], [ColumnDef])
forall e a. Exception e => e -> IO a
throwIO (ERRException -> IO (StmtPrepareOK, [ColumnDef], [ColumnDef]))
-> (ERR -> ERRException)
-> ERR
-> IO (StmtPrepareOK, [ColumnDef], [ColumnDef])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
else do
sOK :: StmtPrepareOK
sOK@(StmtPrepareOK StmtID
_ Int
colCnt Int
paramCnt Int
_) <- Get StmtPrepareOK -> Packet -> IO StmtPrepareOK
forall a. Get a -> Packet -> IO a
getFromPacket Get StmtPrepareOK
getStmtPrepareOK Packet
p
[ColumnDef]
pdefs <- Int -> IO ColumnDef -> IO [ColumnDef]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
paramCnt ((Packet -> IO ColumnDef
forall a. Binary a => Packet -> IO a
decodeFromPacket (Packet -> IO ColumnDef)
-> (InputStream Packet -> IO Packet)
-> InputStream Packet
-> IO ColumnDef
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< InputStream Packet -> IO Packet
readPacket) InputStream Packet
is)
()
_ <- Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
paramCnt Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (IO Packet -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (InputStream Packet -> IO Packet
readPacket InputStream Packet
is))
[ColumnDef]
cdefs <- Int -> IO ColumnDef -> IO [ColumnDef]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
colCnt ((Packet -> IO ColumnDef
forall a. Binary a => Packet -> IO a
decodeFromPacket (Packet -> IO ColumnDef)
-> (InputStream Packet -> IO Packet)
-> InputStream Packet
-> IO ColumnDef
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< InputStream Packet -> IO Packet
readPacket) InputStream Packet
is)
()
_ <- Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
colCnt Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (IO Packet -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (InputStream Packet -> IO Packet
readPacket InputStream Packet
is))
(StmtPrepareOK, [ColumnDef], [ColumnDef])
-> IO (StmtPrepareOK, [ColumnDef], [ColumnDef])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (StmtPrepareOK
sOK, [ColumnDef]
pdefs, [ColumnDef]
cdefs)
closeStmt :: MySQLConn -> StmtID -> IO ()
closeStmt :: MySQLConn -> StmtID -> IO ()
closeStmt (MySQLConn InputStream Packet
_ Packet -> IO ()
os IO ()
_ IORef Bool
_) StmtID
stid = do
Command -> (Packet -> IO ()) -> IO ()
writeCommand (StmtID -> Command
COM_STMT_CLOSE StmtID
stid) Packet -> IO ()
os
resetStmt :: MySQLConn -> StmtID -> IO ()
resetStmt :: MySQLConn -> StmtID -> IO ()
resetStmt (MySQLConn InputStream Packet
is Packet -> IO ()
os IO ()
_ IORef Bool
consumed) StmtID
stid = do
Command -> (Packet -> IO ()) -> IO ()
writeCommand (StmtID -> Command
COM_STMT_RESET StmtID
stid) Packet -> IO ()
os
Packet
p <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
if Packet -> Bool
isERR Packet
p
then Packet -> IO ERR
forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
p IO ERR -> (ERR -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ERRException -> IO ()
forall e a. Exception e => e -> IO a
throwIO (ERRException -> IO ()) -> (ERR -> ERRException) -> ERR -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
else IORef Bool -> Bool -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
True
executeStmt :: MySQLConn -> StmtID -> [MySQLValue] -> IO OK
executeStmt :: MySQLConn -> StmtID -> [MySQLValue] -> IO OK
executeStmt MySQLConn
conn StmtID
stid [MySQLValue]
params =
MySQLConn -> Command -> IO OK
command MySQLConn
conn (StmtID -> [MySQLValue] -> BitMap -> Command
COM_STMT_EXECUTE StmtID
stid [MySQLValue]
params ([MySQLValue] -> BitMap
makeNullMap [MySQLValue]
params))
queryStmt :: MySQLConn -> StmtID -> [MySQLValue] -> IO ([ColumnDef], InputStream [MySQLValue])
queryStmt :: MySQLConn
-> StmtID
-> [MySQLValue]
-> IO ([ColumnDef], InputStream [MySQLValue])
queryStmt conn :: MySQLConn
conn@(MySQLConn InputStream Packet
is Packet -> IO ()
os IO ()
_ IORef Bool
consumed) StmtID
stid [MySQLValue]
params = do
MySQLConn -> IO ()
guardUnconsumed MySQLConn
conn
Command -> (Packet -> IO ()) -> IO ()
writeCommand (StmtID -> [MySQLValue] -> BitMap -> Command
COM_STMT_EXECUTE StmtID
stid [MySQLValue]
params ([MySQLValue] -> BitMap
makeNullMap [MySQLValue]
params)) Packet -> IO ()
os
Packet
p <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
if Packet -> Bool
isERR Packet
p
then Packet -> IO ERR
forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
p IO ERR
-> (ERR -> IO ([ColumnDef], InputStream [MySQLValue]))
-> IO ([ColumnDef], InputStream [MySQLValue])
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ERRException -> IO ([ColumnDef], InputStream [MySQLValue])
forall e a. Exception e => e -> IO a
throwIO (ERRException -> IO ([ColumnDef], InputStream [MySQLValue]))
-> (ERR -> ERRException)
-> ERR
-> IO ([ColumnDef], InputStream [MySQLValue])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
else do
Int
len <- Get Int -> Packet -> IO Int
forall a. Get a -> Packet -> IO a
getFromPacket Get Int
getLenEncInt Packet
p
[ColumnDef]
fields <- Int -> IO ColumnDef -> IO [ColumnDef]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
len (IO ColumnDef -> IO [ColumnDef]) -> IO ColumnDef -> IO [ColumnDef]
forall a b. (a -> b) -> a -> b
$ (Packet -> IO ColumnDef
forall a. Binary a => Packet -> IO a
decodeFromPacket (Packet -> IO ColumnDef)
-> (InputStream Packet -> IO Packet)
-> InputStream Packet
-> IO ColumnDef
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< InputStream Packet -> IO Packet
readPacket) InputStream Packet
is
Packet
_ <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
IORef Bool -> Bool -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
False
InputStream [MySQLValue]
rows <- IO (Maybe [MySQLValue]) -> IO (InputStream [MySQLValue])
forall a. IO (Maybe a) -> IO (InputStream a)
Stream.makeInputStream (IO (Maybe [MySQLValue]) -> IO (InputStream [MySQLValue]))
-> IO (Maybe [MySQLValue]) -> IO (InputStream [MySQLValue])
forall a b. (a -> b) -> a -> b
$ do
Packet
q <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
if | Packet -> Bool
isOK Packet
q -> [MySQLValue] -> Maybe [MySQLValue]
forall a. a -> Maybe a
Just ([MySQLValue] -> Maybe [MySQLValue])
-> IO [MySQLValue] -> IO (Maybe [MySQLValue])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get [MySQLValue] -> Packet -> IO [MySQLValue]
forall a. Get a -> Packet -> IO a
getFromPacket ([ColumnDef] -> Int -> Get [MySQLValue]
getBinaryRow [ColumnDef]
fields Int
len) Packet
q
| Packet -> Bool
isEOF Packet
q -> IORef Bool -> Bool -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
True IO () -> IO (Maybe [MySQLValue]) -> IO (Maybe [MySQLValue])
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe [MySQLValue] -> IO (Maybe [MySQLValue])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe [MySQLValue]
forall a. Maybe a
Nothing
| Packet -> Bool
isERR Packet
q -> Packet -> IO ERR
forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
q IO ERR
-> (ERR -> IO (Maybe [MySQLValue])) -> IO (Maybe [MySQLValue])
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ERRException -> IO (Maybe [MySQLValue])
forall e a. Exception e => e -> IO a
throwIO (ERRException -> IO (Maybe [MySQLValue]))
-> (ERR -> ERRException) -> ERR -> IO (Maybe [MySQLValue])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
| Bool
otherwise -> UnexpectedPacket -> IO (Maybe [MySQLValue])
forall e a. Exception e => e -> IO a
throwIO (Packet -> UnexpectedPacket
UnexpectedPacket Packet
q)
([ColumnDef], InputStream [MySQLValue])
-> IO ([ColumnDef], InputStream [MySQLValue])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([ColumnDef]
fields, InputStream [MySQLValue]
rows)
queryStmtVector :: MySQLConn -> StmtID -> [MySQLValue] -> IO (V.Vector ColumnDef, InputStream (V.Vector MySQLValue))
queryStmtVector :: MySQLConn
-> StmtID
-> [MySQLValue]
-> IO (Vector ColumnDef, InputStream (Vector MySQLValue))
queryStmtVector conn :: MySQLConn
conn@(MySQLConn InputStream Packet
is Packet -> IO ()
os IO ()
_ IORef Bool
consumed) StmtID
stid [MySQLValue]
params = do
MySQLConn -> IO ()
guardUnconsumed MySQLConn
conn
Command -> (Packet -> IO ()) -> IO ()
writeCommand (StmtID -> [MySQLValue] -> BitMap -> Command
COM_STMT_EXECUTE StmtID
stid [MySQLValue]
params ([MySQLValue] -> BitMap
makeNullMap [MySQLValue]
params)) Packet -> IO ()
os
Packet
p <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
if Packet -> Bool
isERR Packet
p
then Packet -> IO ERR
forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
p IO ERR
-> (ERR -> IO (Vector ColumnDef, InputStream (Vector MySQLValue)))
-> IO (Vector ColumnDef, InputStream (Vector MySQLValue))
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ERRException
-> IO (Vector ColumnDef, InputStream (Vector MySQLValue))
forall e a. Exception e => e -> IO a
throwIO (ERRException
-> IO (Vector ColumnDef, InputStream (Vector MySQLValue)))
-> (ERR -> ERRException)
-> ERR
-> IO (Vector ColumnDef, InputStream (Vector MySQLValue))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
else do
Int
len <- Get Int -> Packet -> IO Int
forall a. Get a -> Packet -> IO a
getFromPacket Get Int
getLenEncInt Packet
p
Vector ColumnDef
fields <- Int -> IO ColumnDef -> IO (Vector ColumnDef)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
len (IO ColumnDef -> IO (Vector ColumnDef))
-> IO ColumnDef -> IO (Vector ColumnDef)
forall a b. (a -> b) -> a -> b
$ (Packet -> IO ColumnDef
forall a. Binary a => Packet -> IO a
decodeFromPacket (Packet -> IO ColumnDef)
-> (InputStream Packet -> IO Packet)
-> InputStream Packet
-> IO ColumnDef
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< InputStream Packet -> IO Packet
readPacket) InputStream Packet
is
Packet
_ <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
IORef Bool -> Bool -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
False
InputStream (Vector MySQLValue)
rows <- IO (Maybe (Vector MySQLValue))
-> IO (InputStream (Vector MySQLValue))
forall a. IO (Maybe a) -> IO (InputStream a)
Stream.makeInputStream (IO (Maybe (Vector MySQLValue))
-> IO (InputStream (Vector MySQLValue)))
-> IO (Maybe (Vector MySQLValue))
-> IO (InputStream (Vector MySQLValue))
forall a b. (a -> b) -> a -> b
$ do
Packet
q <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
if | Packet -> Bool
isOK Packet
q -> Vector MySQLValue -> Maybe (Vector MySQLValue)
forall a. a -> Maybe a
Just (Vector MySQLValue -> Maybe (Vector MySQLValue))
-> IO (Vector MySQLValue) -> IO (Maybe (Vector MySQLValue))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get (Vector MySQLValue) -> Packet -> IO (Vector MySQLValue)
forall a. Get a -> Packet -> IO a
getFromPacket (Vector ColumnDef -> Int -> Get (Vector MySQLValue)
getBinaryRowVector Vector ColumnDef
fields Int
len) Packet
q
| Packet -> Bool
isEOF Packet
q -> IORef Bool -> Bool -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
True IO ()
-> IO (Maybe (Vector MySQLValue)) -> IO (Maybe (Vector MySQLValue))
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe (Vector MySQLValue) -> IO (Maybe (Vector MySQLValue))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Vector MySQLValue)
forall a. Maybe a
Nothing
| Packet -> Bool
isERR Packet
q -> Packet -> IO ERR
forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
q IO ERR
-> (ERR -> IO (Maybe (Vector MySQLValue)))
-> IO (Maybe (Vector MySQLValue))
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ERRException -> IO (Maybe (Vector MySQLValue))
forall e a. Exception e => e -> IO a
throwIO (ERRException -> IO (Maybe (Vector MySQLValue)))
-> (ERR -> ERRException) -> ERR -> IO (Maybe (Vector MySQLValue))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
| Bool
otherwise -> UnexpectedPacket -> IO (Maybe (Vector MySQLValue))
forall e a. Exception e => e -> IO a
throwIO (Packet -> UnexpectedPacket
UnexpectedPacket Packet
q)
(Vector ColumnDef, InputStream (Vector MySQLValue))
-> IO (Vector ColumnDef, InputStream (Vector MySQLValue))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Vector ColumnDef
fields, InputStream (Vector MySQLValue)
rows)
withTransaction :: MySQLConn -> IO a -> IO a
withTransaction :: forall a. MySQLConn -> IO a -> IO a
withTransaction MySQLConn
conn IO a
procedure = ((forall a. IO a -> IO a) -> IO a) -> IO a
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
mask (((forall a. IO a -> IO a) -> IO a) -> IO a)
-> ((forall a. IO a -> IO a) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
restore -> do
OK
_ <- MySQLConn -> Query -> IO OK
execute_ MySQLConn
conn Query
"BEGIN"
a
r <- IO a -> IO a
forall a. IO a -> IO a
restore IO a
procedure IO a -> IO OK -> IO a
forall a b. IO a -> IO b -> IO a
`onException` (MySQLConn -> Query -> IO OK
execute_ MySQLConn
conn Query
"ROLLBACK")
OK
_ <- MySQLConn -> Query -> IO OK
execute_ MySQLConn
conn Query
"COMMIT"
a -> IO a
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
r