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.Applicative
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 (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
";" forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (Query -> ByteString
fromQuery forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t 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 (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 (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 forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
p forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall e a. Exception e => e -> IO a
throwIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
else do
Int
len <- forall a. Get a -> Packet -> IO a
getFromPacket Get Int
getLenEncInt Packet
p
[ColumnDef]
fields <- forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
len forall a b. (a -> b) -> a -> b
$ (forall a. Binary a => Packet -> IO a
decodeFromPacket 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
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
False
InputStream [MySQLValue]
rows <- forall a. IO (Maybe a) -> IO (InputStream a)
Stream.makeInputStream forall a b. (a -> b) -> a -> b
$ do
Packet
q <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
if | Packet -> Bool
isEOF Packet
q -> forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
True forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
| Packet -> Bool
isERR Packet
q -> forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
q forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall e a. Exception e => e -> IO a
throwIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
| Bool
otherwise -> forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Get a -> Packet -> IO a
getFromPacket ([ColumnDef] -> Get [MySQLValue]
getTextRow [ColumnDef]
fields) Packet
q
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 forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
p forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall e a. Exception e => e -> IO a
throwIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
else do
Int
len <- forall a. Get a -> Packet -> IO a
getFromPacket Get Int
getLenEncInt Packet
p
Vector ColumnDef
fields <- forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
len forall a b. (a -> b) -> a -> b
$ (forall a. Binary a => Packet -> IO a
decodeFromPacket 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
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
False
InputStream (Vector MySQLValue)
rows <- forall a. IO (Maybe a) -> IO (InputStream a)
Stream.makeInputStream forall a b. (a -> b) -> a -> b
$ do
Packet
q <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
if | Packet -> Bool
isEOF Packet
q -> forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
True forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
| Packet -> Bool
isERR Packet
q -> forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
q forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall e a. Exception e => e -> IO a
throwIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
| Bool
otherwise -> forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Get a -> Packet -> IO a
getFromPacket (Vector ColumnDef -> Get (Vector MySQLValue)
getTextRowVector Vector ColumnDef
fields) Packet
q
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 forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
p forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall e a. Exception e => e -> IO a
throwIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
else do
StmtPrepareOK StmtID
stid Int
colCnt Int
paramCnt Int
_ <- forall a. Get a -> Packet -> IO a
getFromPacket Get StmtPrepareOK
getStmtPrepareOK Packet
p
()
_ <- forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
replicateM_ Int
paramCnt (InputStream Packet -> IO Packet
readPacket InputStream Packet
is)
()
_ <- forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
paramCnt forall a. Eq a => a -> a -> Bool
== Int
0) (forall (f :: * -> *) a. Functor f => f a -> f ()
void (InputStream Packet -> IO Packet
readPacket InputStream Packet
is))
()
_ <- forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
replicateM_ Int
colCnt (InputStream Packet -> IO Packet
readPacket InputStream Packet
is)
()
_ <- forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
colCnt forall a. Eq a => a -> a -> Bool
== Int
0) (forall (f :: * -> *) a. Functor f => f a -> f ()
void (InputStream Packet -> IO Packet
readPacket InputStream Packet
is))
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 forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
p forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall e a. Exception e => e -> IO a
throwIO 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
_) <- forall a. Get a -> Packet -> IO a
getFromPacket Get StmtPrepareOK
getStmtPrepareOK Packet
p
[ColumnDef]
pdefs <- forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
paramCnt ((forall a. Binary a => Packet -> IO a
decodeFromPacket forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< InputStream Packet -> IO Packet
readPacket) InputStream Packet
is)
()
_ <- forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
paramCnt forall a. Eq a => a -> a -> Bool
== Int
0) (forall (f :: * -> *) a. Functor f => f a -> f ()
void (InputStream Packet -> IO Packet
readPacket InputStream Packet
is))
[ColumnDef]
cdefs <- forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
colCnt ((forall a. Binary a => Packet -> IO a
decodeFromPacket forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< InputStream Packet -> IO Packet
readPacket) InputStream Packet
is)
()
_ <- forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
colCnt forall a. Eq a => a -> a -> Bool
== Int
0) (forall (f :: * -> *) a. Functor f => f a -> f ()
void (InputStream Packet -> IO Packet
readPacket InputStream Packet
is))
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 forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
p forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall e a. Exception e => e -> IO a
throwIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
else 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 forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
p forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall e a. Exception e => e -> IO a
throwIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
else do
Int
len <- forall a. Get a -> Packet -> IO a
getFromPacket Get Int
getLenEncInt Packet
p
[ColumnDef]
fields <- forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
len forall a b. (a -> b) -> a -> b
$ (forall a. Binary a => Packet -> IO a
decodeFromPacket 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
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
False
InputStream [MySQLValue]
rows <- forall a. IO (Maybe a) -> IO (InputStream a)
Stream.makeInputStream forall a b. (a -> b) -> a -> b
$ do
Packet
q <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
if | Packet -> Bool
isOK Packet
q -> forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Get a -> Packet -> IO a
getFromPacket ([ColumnDef] -> Int -> Get [MySQLValue]
getBinaryRow [ColumnDef]
fields Int
len) Packet
q
| Packet -> Bool
isEOF Packet
q -> forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
True forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
| Packet -> Bool
isERR Packet
q -> forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
q forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall e a. Exception e => e -> IO a
throwIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
| Bool
otherwise -> forall e a. Exception e => e -> IO a
throwIO (Packet -> UnexpectedPacket
UnexpectedPacket Packet
q)
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 forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
p forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall e a. Exception e => e -> IO a
throwIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
else do
Int
len <- forall a. Get a -> Packet -> IO a
getFromPacket Get Int
getLenEncInt Packet
p
Vector ColumnDef
fields <- forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
len forall a b. (a -> b) -> a -> b
$ (forall a. Binary a => Packet -> IO a
decodeFromPacket 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
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
False
InputStream (Vector MySQLValue)
rows <- forall a. IO (Maybe a) -> IO (InputStream a)
Stream.makeInputStream forall a b. (a -> b) -> a -> b
$ do
Packet
q <- InputStream Packet -> IO Packet
readPacket InputStream Packet
is
if | Packet -> Bool
isOK Packet
q -> forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> 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 -> forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
consumed Bool
True forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
| Packet -> Bool
isERR Packet
q -> forall a. Binary a => Packet -> IO a
decodeFromPacket Packet
q forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall e a. Exception e => e -> IO a
throwIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. ERR -> ERRException
ERRException
| Bool
otherwise -> forall e a. Exception e => e -> IO a
throwIO (Packet -> UnexpectedPacket
UnexpectedPacket Packet
q)
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 b. ((forall a. IO a -> IO a) -> IO b) -> IO b
mask 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 <- forall a. IO a -> IO a
restore IO a
procedure 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"
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
r